Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I throw Exception for async function using Moq

I am writing test cases using xUnit and Moq.

I am using below code in Test class for testing catch() of another class method

private readonly  IADLS_Operations _iADLS_Operations;

[Fact]
public void CreateCSVFile_Failure()
{
    var dtData = new DataTable();
    string fileName = "";
   var   mockClient = new Mock<IHttpHandler>();

    this._iADLS_Operations = new ADLS_Operations(mockClient.Object);

    mockClient.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
        .Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));

    mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
        .Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));  // here I want to return Exception instead of BadRequest. How to do that.

    Exception ex = Assert.Throws<Exception>(() => this._iADLS_Operations.CreateCSVFile(dtData, fileName).Result);
    Assert.Contains("Exception occurred while executing method:", ex.Message);
}

In below code, I want to return Exception instead of BadRequest.

mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
    .Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));

How to achieve that.

like image 378
chandra sekhar Avatar asked Jul 18 '19 12:07

chandra sekhar


People also ask

How do you get async exceptions?

Implement try-catch within the function This is the solution to catch exceptions in asynchronous methods. Have a look at the following code. If you look closely inside the ShowAsync() function, then you will find we have implemented a try-catch within Task.

Are exceptions handled asynchronously?

Learn the exception handling semantics for asynchronous methods in C# Exception handling is the technique of handling runtime errors in an application. Asynchronous programming allows us to perform resource-intensive operations without the need for blocking on the main or executing thread of the application.


1 Answers

Considering the asynchronous nature of the code under test, it would be better if the test code be asynchronous as well. Moq is async capable

[Fact]
public async Task CreateCSVFile_Failure() {
    //Arrange
    var dtData = new DataTable();
    string fileName = "";
    var mockClient = new Mock<IHttpHandler>();

    this._iADLS_Operations = new ADLS_Operations(mockClient.Object);

    mockClient
        .Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
        .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadRequest));

    mockClient
        .Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
        .ThrowsAsync(new Exception("Some message here"));

    //Act 
    Func<Task> act = () => this._iADLS_Operations.CreateCSVFile(dtData, fileName);

    //Assert
    Exception ex = await Assert.ThrowsAsync<Exception>(act);
    Assert.Contains("Exception occurred while executing method:", ex.Message);
}

Note the use of Moq's ReturnsAsync and ThrowsAsync in the setup, along with xUnit's Assert.ThrowsAsync

This now allows you to avoid making blocking calls like .Result which could potentially lead to deadlocks.

like image 154
Nkosi Avatar answered Nov 15 '22 12:11

Nkosi