如何正确测试返回json以获取非null响应的API控制器?

时间:2015-07-10 13:01:18

标签: c# json moq asp.net-web-api2 mstest

我有这个测试方法来测试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仍然如下:
  2. { categories = {int[0]}, series = { name = "Number of colors", data = {double[0]} } }

    1. contentResult.ContentNegotiatorcontentResult.FormattercontentResult.Request所有人都将InvalidOperationException的例外情况与HttpControllerContext.Configuration must not be null.一起消息我不知道为什么会发生这种情况
    2. 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; }
      }
      

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

1 个答案:

答案 0 :(得分:11)

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

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