Search code examples
c#asp.net-coretddxunithttp-status-code-500

Using Xunit in .Net core web API - How to test/ pass 500 status code


We are trying the Test Driven Development for our .Net core 3.1 Web API and using XUnit for the same.

In my controller, I have test cases or [Fact] written for the status codes 200,404 and other scenarios.

When it comes to unit testing 500 internal server error - I am not sure how to pass the code, or how to assert it.

It always fails for me by using the below code.

How to successfully test the 500 - Internal server error in my unit test?

I am very new to TDD any comment is helpful, below is the code :

[Fact] // 404 Sample unit test method
public async Task Get_OnNotFound_Returns404()
{
    // Arrange
    var mockService = new Mock<IService>();

    mockService.Setup(service => service.GetTypes(It.IsAny<string>(), 
        It.IsAny<CancellationToken>())).ReturnsAsync(new List<TypeResponse>());

    var sut = new HomeController(mockService.Object);

    //Act
    var result = await sut.GetSampleMethod("foo") as ObjectResult;

    //Assert

    Assert.Equal(StatusCodes.Status404NotFound, result.StatusCode);
}


// Below is my always failing 500 code unit test

[Fact]
public async Task Returns_500_When_Returns_Error()
{
    // Arrange
    var mockService = new Mock<IService>();

    mockService.Setup(service => service.GetTypes(It.IsAny<string>(),
        It.IsAny<CancellationToken>())).ReturnsAsync(new List<TypeResponse>());

    var sut = new HomeController(mockService.Object);

    //Act
    var result = await GetSampleMethod("foo") as ObjectResult;

    //Assert
    Assert.Equal(StatusCodes.Status500InternalServerError, result.StatusCode);
}

Below is my controller method :

[HttpGet]
public async Task<IActionResult> GetSampleMethod(string id, 
    CancellationToken cancellationToken)
{
    try
    {
        var result = await _service.GetSampleMethod(id, cancellationToken);
        if (result.Any())
        {
            return Ok(result);
        }

        return StatusCode(StatusCodes.Status404NotFound,
            new Error { Message = "No Records ." });
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError,
            new Error
            {
                Message = !string.IsNullOrWhiteSpace(ex.Message)
                    ? ex.Message : "An unhandled error occurred."
            });
    }
}

Solution

  • It's clear that your method returns Status500InternalServerError in case of an exception. So you have to mock an exception for it:

    mockService.Setup(service => service.GetTypes(It.IsAny<string>(),
         It.IsAny<CancellationToken>()))
           .Throws(new Exception());