如何正确测试返回json的非空响应的API控制器
本文关键字:响应 API 控制器 测试 返回 json 何正确 | 更新日期: 2023-09-27 18:02:09
我有这个测试方法用于测试API控制器,它返回一个JSON字符串,用于非空响应。
[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);
}
}
此测试通过,因为contentResult
不为空。然而,由于以下原因,我不确定测试是否写得正确:
-
contentResult.Content
有空数据,因为没有数据从_repository.GetChartData()
方法返回,但不是空的,因为仍然构造的json如下所示:
{ categories = {int[0]}, series = { name = "Number of colors", data = {double[0]} } }
-
contentResult.ContentNegotiator
,contentResult.Formatter
和contentResult.Request
都抛出了InvalidOperationException
的异常,消息HttpControllerContext.Configuration must not be null.
我不知道为什么会发生这种情况。API控制器:
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); }
从存储库实现返回的对象:
public class ColorPerformanceChartData { private double _cumulativePercentage; public double CumulativePercentage { get { return Math.Round(_cumulativePercentage, 2); } set { _cumulativePercentage = value; } } public int Id { get; set; } }
我在这里错过了什么或做错了什么?
最好的做法是在这种情况下避免使用匿名类型:
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() }}
};
}
尝试为它定义一个类,以便您可以反序列化字符串并检查每个属性:
// 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,..
对于异常,尝试:
var controller = new ColorPerformanceController(mockRepository.Object);
//Add these 2 lines
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
从http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api