首页 > 解决方案 > 如何在 C# 中测试列表作为函数的结果

问题描述

对于我的公司,我正在使用 .NET Core 3.x 创建一个 Azure Functions 来生成发票。我必须考虑不同的场景,我想为此创建一个测试。

我想创建一个函数,在其中传递发票的行列表。在此功能中,我必须检查用户是否有任何退款:如果有,我必须从当前发票中扣除金额。如果有一些要退款的钱,我必须创建一个新的退款发票。

public class InvoiceGeneratorResponse
{
    public List<InvoiceGeneratorDetailResponse> Details { get; set; }
    public List<InvoiceGeneratorErrorResponse> Errors { get; set; }
    public List<InvoiceGeneratorNextInvoiceResponse> NextInvoice { get; set; }
}

InvoiceGeneratorResponse是我的课程的结果,其中Details是发票列表,Errors是不完整发票的列表,NextInvoice是我必须创建的退款发票列表。

现在,我想创建一堆测试来检查每个场景。为此,我必须将行列表传递给该函数并检查结果。

我正在考虑从文件中读取行列表json并将其转换为列表以传递给函数。对于我想读取另一个文件的结果,将其转换为列表并将文件中的列表与函数的结果进行比较。

是否已经有用于在测试中读取文件的注释?如果是,使用什么框架?xUnit? nUnit? 有没有一种简单的方法可以在测试中完全比较两个列表?

标签: c#unit-testingnunitxunit.net

解决方案


是否已经有用于在测试中读取文件的注释?如果是,使用什么框架?单位?单位?

不是我所知道的,它必须是一种非常特殊的格式,可以用于某些目的,但对于其他目的却缺乏。因此,如果一个框架能够读取 JSON,它们也必须支持它,并且请求也会支持 XML 和 OpenXML 等等,所以我可以看到为什么测试框架不支持它了盒子。

但是,您可以使用属性为使用各种框架的测试提供输入参数:

具有属性值的MSTest(“数据驱动测试”):

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
[DataRow(12,4,3)]
public void DivideTest(int n, int d, int q)
{
     Assert.AreEqual(q, n / d);
}

NUnit(“参数化测试”)与数组中的值:

[TestCaseSource("DivideCases")]
public void DivideTest(int n, int d, int q)
{
    Assert.AreEqual(q, n / d);
}

static object[] DivideCases =
{
    new object[] { 12, 3, 4 },
    new object[] { 12, 2, 6 },
    new object[] { 12, 4, 3 }
};

并且 xUnit可以扩展从属性中指定的 JSON 文件中读取数据,依此类推。

但是在您的情况下,如果您只是想准备一个包含所需方法输出的 JSON 文件,您可以使用 Newtonsoft.Json 并CollectionAssert.AreEqual(expected, actual, comparer)使用您自己的比较器来阅读InvoiceGeneratorDetailResponse

public void Foo_Bars_The_Foo()
{
    // Arrange
    var classUnderTest = ...
    var expectedJson = File.ReadAllText("bar_output.json");
    var expected = JsonConvert.DeserializeObject<List<InvoiceGeneratorDetailResponse>>(expectedJson);
    
    // Act
    var result = classUnderTest...  
    
    // Assert
    var invoiceDetailComparer = new ...
    CollectionAssert.AreEqual(expected, result, invoiceDetailComparer);
}

推荐阅读