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

C# 如何正确测试返回json的非空响应的API控制器?,c#,json,moq,asp.net-web-api2,mstest,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

我有这个测试方法来测试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);
    }
}
IColorPerformanceRepository:

public interface IColorPerformanceRepository
{
    IEnumerable<ColorPerformanceChartData> GetChartData(string quality, string cars, string year);
}

我在这里遗漏了什么或做错了什么?

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

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,..

中,您是否尝试调试测试,以查看它将错误抛出的位置?是的,我调试了测试,但测试并没有真正失败。如前所述,测试通过了。只是我没有看到来自
\u repository.GetChartData()
调用的任何数据。这是因为我只是在嘲笑行为还是我应该得到数据,因为你提到,
…和contentResult.Request都抛出了InvalidOperationException的异常…
我真的不确定我所做的测试是否足够,因为我提到了两个原因。我本来希望从
\u repository.GetChartData()
方法中获得一些数据,但后来意识到MockRepository并没有真正调用实际的repository方法。我知道最好避免匿名类型,但是选择匿名对象的原因是以前端图表库可以接受的特定格式创建JSON字符串。@Animesh:我不明白为什么这个原因限制您使用匿名类型。没有绝对的原因,它是根据不断变化的需求快速创建的。但除了通过返回强类型类在可读性和可维护性方面有了巨大的改进之外,我很想知道是否还有其他优势。我想补充一点,我迟早会咬紧牙关创建强类型类。@Animesh:我认为它们是主要的优势。我认为另一个优点是,在这种情况下,您可以在编译时访问它的属性
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();