Search code examples
unit-testingtestingassertxunitassertion

XUnit: How to assert exception thrown by the controller in ASP.NET Core


I have a method inside the controller, which does some checks when the check is not true, it will throw an error. How I will catch that error thrown by the API with the specific message?

I`m confused about how to make those types of assertions.

This is my code so far, but I didn't manage to catch the error thrown by the controller. What I'm doing wrong?

[Fact]
    public async Task AppendEmailBase64Dto_InvalidBase64_ReturnBadRequest()
    {
        // Arrange
        var emailControllerMocks = new EmailControllerMocks();
        var mockLogger = emailControllerMocks.MockLogger();
        var mockMapper = emailControllerMocks.MockMapper();
        var mockEmsWorkUnit = emailControllerMocks.MockEmsWorkUnit();
        var mockAzureBlob = emailControllerMocks.MockAzureBlobAndGetTemplate();

        // Setup
        var userRequestTemplateString = File.ReadAllText(@".\EmailController\UserRequestTemplate.txt");
        mockAzureBlob.Setup(blob => blob.GetHtmlBlob(It.IsAny<string>(), It.IsAny<Uri>()))
            .ReturnsAsync(userRequestTemplateString);


        // Act
        var emailController = new Controllers.ApiV10.EmailController(mockLogger.Object, mockMapper.Object, mockEmsWorkUnit.Object, mockAzureBlob.Object);
        var jsonString = File.ReadAllText(@".\EmailController\TemplateBase64Invalid.json");
        var testEmailBase64Dto = GeneralHelpers.Deserialize<EmailBase64Dto>(jsonString);

        var badRequestResult = await emailController.AppendEmailBase64Dto(testEmailBase64Dto);
        //var result = badRequestResult.Value as ObjectResult;
        //var errorMessage = badRequestResult.Value as List<string>;
        //var statusCode = badRequestResult.StatusCode;

        // Assert
        //Assert.Equal("The provided base64 template is not a valid base64 string", errorMessage[0]);
        //Assert.Equal(400, statusCode);
    }

Solution

  • Use Assert.ThrowsAsync (the asynchronous counterpart of Assert.Throws) to assert that an exception of a particular type is thrown.

    In your case you'll want something like:

    var ex = await Assert.ThrowsAsync<HttpException>(async () => await emailController.AppendEmailBase64Dto(testEmailBase64Dto));
    

    Obviously adjust 'HttpException' to whatever type of exception you're expecting. You're not going to be able to check the return type in the same test (because AppendEmailBase64Dto will not return when an exception is thrown), so you'll need to test the exception in a separate test.