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.
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.