Home > Software design >  Unit Testing a Controller method returns null
Unit Testing a Controller method returns null

Time:07-27

I'm trying to learn Unit testing in .NET 6 by testing a controller function GetProduct. The problem is I get null returned in the variable var product = await _productController.GetProduct(productId);. As you can see in the picture below, the Result is ok but the Value, where the ServiceResponse<Product> was suppose to be is null.

enter image description here

Here is the controller function:

public class ProductController : ControllerBase
{
    private readonly IProductService _productService;

    public ProductController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet("{productId}")]
    public async Task<ActionResult<ServiceResponse<Product>>> GetProduct(int productId)
    {
        var result = await _productService.GetProductAsync(productId);
        return Ok(result);
    }
}

Here is the Test:

public class ProductControllerTest
{
    private readonly ProductController _productController;
    private readonly Mock<IProductService> _productService = new Mock<IProductService>();

    public ProductControllerTest()
    {
        _productController = new ProductController(_productService.Object);
    }    

    [Test]
    public async Task GetProducts_ReturnsProduct_IfProductExists()
    {
        //Arange
        var productId = 1;
        var prodData = new Product
        {
            Id = productId,
            Title = "null"            
        };
        var prductResponse = new ServiceResponse<Product>
        {
            Data = prodData,
            Success = true ,
            Message = ""
        };

        _productService.Setup(x => x.GetProductAsync(productId)).ReturnsAsync(prductResponse);

        //Act
        var product = await _productController.GetProduct(productId);

        //Assert
        Assert.That(product?.Value?.Data?.Id, Is.EqualTo(productId));
    }

}

CodePudding user response:

Since you are returning with an Ok call in your controller you can add a cast to the unit test.

   var result = (await _productController.GetProduct(productId)).Result as OkObjectResult;
   Assert.IsNotNull(result);
   var returnedServiceResponse = result.Value as ServiceResponse<Product>;
   Assert.That(returnedServiceResponse ?.Data?.Id, Is.EqualTo(productId));

Also you don't have to use Actionresult. You can also just return your service response

   [HttpGet("{productId}")]
    public async Task<ServiceResponse<Product>> GetProduct(int productId)
    {
        var result = await _productService.GetProductAsync(productId);
        return result;
    }

This will also make the test a bit easier as no need to use the OkObjectResult.

  • Related