I have this test method for testing an API controller, that returns a JSON string, for a non null response.
[TestClass]
public class TransactionsTests
{
[TestMethod]
public void ColorPerformance_GetChartData_NotNullResponse_Test()
{
// Arrange
string quality = null, cars = null, year = "2015";
var listColorPerformanceChartData = new List<ColorPerformanceChartData>();
var mockRepository = new Mock<IColorPerformanceRepository>();
mockRepository.Setup(x => x.GetChartData(quality, cars, year))
.Returns(listColorPerformanceChartData);
var controller = new ColorPerformanceController(mockRepository.Object);
// Act
IHttpActionResult actionResult = controller.GetChartData(quality, cars, year);
var contentResult = actionResult as OkNegotiatedContentResult<object>;
// Assert
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
}
}
This test is passing in that contentResult
is not null. However, I am not feeling sure that the test is written properly for the following reasons:
contentResult.Content
has empty data, in that there is no data being returned from _repository.GetChartData()
method, but is not empty because still the json constructed is as follows:{ categories = {int[0]}, series = { name = "Number of colors", data = {double[0]} } }
contentResult.ContentNegotiator
, contentResult.Formatter
and contentResult.Request
all are throwing an exception of InvalidOperationException
with the message HttpControllerContext.Configuration must not be null.
I don't know why this is happening.The API Controller:
public class ColorPerformanceController : ApiController
{
private IColorPerformanceRepository _repository;
public ColorPerformanceController(IColorPerformanceRepository repository)
{
_repository = repository;
}
public IHttpActionResult GetChartData(string quality, string cars, string year)
{
try
{
var data = ProcessData(quality, cars, year);
return Ok(data);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
private object ProcessData(string quality, string cars, string year)
{
var data = _repository.GetChartData(quality, cars, year);
return new {
categories = data.Select(d => d.Id).ToArray(),
series = new[] { new { name = "Number of colors", data = data.Select(d => d.CumulativePercentage).ToArray() }}
};
}
}
IColorPerformanceRepository:
public interface IColorPerformanceRepository
{
IEnumerable<ColorPerformanceChartData> GetChartData(string quality, string cars, string year);
}
The object returned from the repository implementation:
public class ColorPerformanceChartData
{
private double _cumulativePercentage;
public double CumulativePercentage {
get { return Math.Round(_cumulativePercentage, 2); }
set { _cumulativePercentage = value; }
}
public int Id { get; set; }
}
What am I missing or doing wrong here?
Best practice is you should avoid using anonymous type in this case:
private object ProcessData(string quality, string cars, string year)
{
var data = _repository.GetChartData(quality, cars, year);
return new {
categories = data.Select(d => d.Id).ToArray(),
series = new[] { new { name = "Number of colors", data = data.Select(d => d.CumulativePercentage).ToArray() }}
};
}
Try defining a class for it so that you can de-serialize the string and check each property:
// Act
IHttpActionResult actionResult = controller.GetChartData(quality, cars, year);
//Notice I use YourClass instead of object here.
var contentResult = actionResult as OkNegotiatedContentResult<YourClass>;
// Assert
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
//Assert all properties of contentResult.Content like categories, series,..
Regarding the exception, try:
var controller = new ColorPerformanceController(mockRepository.Object);
//Add these 2 lines
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
From http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With