NUnit 测试 returns 列表的控制器方法

NUnit testing a controller method that returns a list

我正在为控制器编写测试 method.This 方法访问 SupplyRepository 中的 getPharmacySupply 方法,其中 return PharmacyMedicineSupply 的列表根据项目要求:

[HttpPost("PharmacySupply")]
public Task<List<PharmacyMedicineSupply>> GetPharmacySupply([FromBody] List<MedicineDemand> medDemand)
{
        _log4net.Info("Get Pharmacy Supply API Acessed");
        return _supplyRepo.GetPharmacySupply(medDemand);
}

这些是我的模型:

public class MedicineStock
{
    public string Name { get; set; }
    public string ChemicalComposition  { get; set; }
    public string TargetAilment { get; set; }
    public DateTime DateOfExpiry { get; set; }
    public int NumberOfTabletsInStock { get; set; }
}

public class PharmacyMedicineSupply
{
    public string pharmacyName { get; set; }
    public List<MedicineNameAndSupply> medicineAndSupply { get; set; }
}

public class MedicineNameAndSupply
{
    public string medicineName { get; set; }
    public int supplyCount { get; set; }
}

这是我正在写的测试:

public static List<MedicineDemand> mockMedicineDemand= new List<MedicineDemand>()
{
            new MedicineDemand()
            {
                Medicine = "Medcine1",
                DemandCount = 20
            },
            new MedicineDemand()
            {
                Medicine = "Medcine2",
                DemandCount = 25
            },
            new MedicineDemand()
            {
                Medicine = "Medcine3",
                DemandCount = 30
            },
            new MedicineDemand()
            {
                Medicine = "Medcine4",
                DemandCount = 35
            },
            new MedicineDemand()
            {
                Medicine = "Medcine5",
                DemandCount = 40
            }

[Test, TestCaseSource(nameof(mockMedicineDemand))]
public void Test_GetPharmacySupply(List<MedicineDemand> mockMedicineDemand)
{
        Mock<ISupplyRepo> supplyMock = new Mock<ISupplyRepo>();
        
        SupplyController sc = new SupplyController(supplyMock.Object);
        var result = sc.GetPharmacySupply(mockMedicineDemand) as Task<List<PharmacyMedicineSupply>>;
        var resultList = result.Result;
        Assert.That(4,Is.EqualTo( resultList[0].medicineAndSupply[0].supplyCount));
} 

但是我收到这个错误

Object of type 'MedicineSupplyMicroservice.Models.MedicineDemand' cannot be converted to type 'System.Collections.Generic.List`1[MedicineSupplyMicroservice.Models.MedicineDemand]'.

我做错了什么??

您正在测试的方法,GetPharmacySupply 接受一个参数,它是 MedicineDemand 个对象的 List

另一方面,

NUnit 用 单个 MedicineDemand.

调用它

看看你的数据源声明...

public static List<MedicineDemand> mockMedicineDemand= new List<MedicineDemand>()
{
   ...
}

TestCaseDataAttribute指定一个字段,属性或方法,return是一个或多个测试用例的必要数据。您的来源是 returning a List<MedicineDemand>,因此 NUnit 获取该列表并使用内容调用您的方法五次,每个 MedicineDemand.

一次。

这显然是一个错误,NUnit 可能对此更聪明一些,并将您的测试标记为非 运行 可用。但是,对于当前版本的 NUnit,它会推迟检查,直到您的测试实际上是 运行。 (一旦您经常使用 TestCaseSource,错误消息就会引导您找到问题所在。)

因此,在这种情况下,您的数据源需要是列表或其他类型的枚举 List<MedicineDemand> - 基本上是列表的列表。

一种方法是使用 List<List<MedicineDemand>>,但我认为这会使代码更加混乱,而不是更少!

这里有很多选项 - 查看 TestCaseSourceAttribute 的文档。我个人的偏好是将数据源做成一个方法,如下:

    public static IEnumerable<List<MedicineDemand>> MockMedicineDemands()
    {
        yield return new List<MedicineDemand>
        {
            new MedicineDemand() { Medicine = "Medicine1", DemandCount = 20 },
            new MedicineDemand() { Medicine = "Medicine2", DemandCount = 25 },
            new MedicineDemand() { Medicine = "Medicine3", DemandCount = 30 },
            new MedicineDemand() { Medicine = "Medicine4", DemandCount = 35 },
            new MedicineDemand() { Medicine = "Medicine5", DemandCount = 40 }
        };

        // Add more cases here if desired

此外,我相信当您 return 一段时间后,代码对其他人和您自己来说都会更清晰,如果您以不同于单个组件的方式命名列表,那就是喜欢 mockMedicineDemandListmockMedicineDemands.

公平警告...我现在不方便编译上面的代码,所以它只是“论坛代码”。错别字等可能性很大。如果您发现任何错误,请 post 发表评论。