c# - 如何正确测试为非空响应返回 json 的 API Controller ?

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

我有这个测试 API Controller 的测试方法,它返回一个 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 = "颜色数", data = {double[0]} } }

  1. contentResult.ContentNegotiatorcontentResult.FormattercontentResult.Request 都抛出 InvalidOperationException 异常消息 HttpControllerContext.Configuration 不能为 null。 我不知道为什么会这样。

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);
}

从存储库实现返回的对象:

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

关于c# - 如何正确测试为非空响应返回 json 的 API Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31341465/

相关文章:

entity-framework - 代码中是否有可以代替 fixture.Inject() 的 Autofixture 属性?

arrays - 尝试使用 PostgreSQL 在 Rails 4 中创建 json 对象数组时出错

c# - 进度条超过最大值

c# - 通过 ignorecase 查找数组索引

c# - 使用ios将视频录制到文件

java - 在 Java 中使用 JSON 的 HTTP POST

javascript - 在 HTA 应用程序中使用 JQUERY 读取 JSON 文件

c# - 如何模拟 ObservableCollection

unit-testing - Moq对IRepository传递表达式的期望

javascript - 为什么我无法使用 JSON 数据?