Search code examples
c#unit-testingexceptionazure-cosmosdbxunit

Test Exceptions in Xunit ()


I am trying to write Xunit test on this method:

public async Task<IEnumerable<T>> RunSQLQueryAsync(string queryString)
{
    try
    {
        //do something
    }
    catch (DocumentClientException e)
    {
        throw new InvalidOperationException(e);
    }

}

Here's the unit test:

[Fact]
public async virtual Task Test_Exception()
{
    var queryString = "SELECT * FROM c";
    var exception = Record.ExceptionAsync(async () => await classname.RunSQLQueryAsync(queryString));
    Assert.NotNull(exception);
    Assert.IsType<DocumentClientException>(exception);
}

But the method failed and it says:

Message: Assert.IsType() Failure Expected: System.DocumentClientException Actual:
System.Threading.Tasks.Task`1[[System.Exception, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxx]]

When I debugged the test, it doesn't go to the catch block. So my question is how to make the unit test expects the method RunSQLQueryAsync to have DocumentClientException?


Solution

  • The test is not awaiting the Task<Exception> returned from Record.ExceptionAsync so the following assertion is actually being done on the Task itself.

    Also the method under test consumes the DocumentClientException and throws a new exception of InvalidOperationException so that is the type that should be expected.

    [Fact]
    public async virtual Task Test_Exception() {
        //Arrange
        var queryString = "SELECT * FROM c";
    
        //Act
        var exception = await Record.ExceptionAsync(() =>
            classname.RunSQLQueryAsync(queryString));
    
        //Assert
        Assert.NotNull(exception);
        Assert.IsType<InvalidOperationException>(exception);
    }
    

    Note the await before the Record.ExceptionAsync

    The assumption is also that the class under test has been setup with a mocked dependency that will throw the desired exception in the //do something part of the provided snippet.