如何正确测试返回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不为空。然而,由于以下原因,我不确定测试是否写得正确:

  1. contentResult.Content有空数据,因为没有数据从_repository.GetChartData()方法返回,但不是空的,因为仍然构造的json如下所示:

{ categories = {int[0]}, series = { name = "Number of colors", data = {double[0]} } }

  • contentResult.ContentNegotiator, contentResult.FormattercontentResult.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; }
    }
    

    我在这里错过了什么或做错了什么?

  • 如何正确测试返回json的非空响应的API控制器

    最好的做法是在这种情况下避免使用匿名类型:

    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