断言所有属性,但有些属性为null

时间:2018-06-13 06:40:31

标签: .net unit-testing testing .net-core nunit

我有映射方法,将模型A映射到模型B。我为那里的所有人写了单元测试。当目标模型具有很多属性时,我想以某种方式很好地处理情况,但大多数都是null。测试目的是测试一些少量的属性是否被正确映射而其他属性没有被映射(除了设计的属性之外没有设置),而不必指定每个属性。

我无法更改B类,因为它通常是我只使用很多属性调用的服务合约。

您能帮忙解释如何简化单元测试吗?

我正在使用.NET Core 2.1和NUnit。

当前状态示例:

public class B
{
    public string Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public string Prop4 { get; set; }
    public string Prop5 { get; set; }
    // a lot of other properties
}

映射方法:

public B Map(A a)
{
    return new B
    {
        Id = a.Id // only Id property is set
    };
}

测试:

[Test]
public void MapTest()
{
    var a = new A { Id = "123" };
    var b = mapping.Map(a);

    Assert.That(b, Is.Not.Null);
    Assert.That(b.Id, Is.EqualTo(a.Id));

    Assert.That(b.Prop1, Is.Null); // this is what i want to simplify
    Assert.That(b.Prop2, Is.Null);
    Assert.That(b.Prop3, Is.Null);
    Assert.That(b.Prop4, Is.Null);
    Assert.That(b.Prop5, Is.Null);
    // a lot of other properties
}

2 个答案:

答案 0 :(得分:0)

FluentAssertions框架具有断言整个对象的功能 创建预期的实例并根据map方法的实际结果进行断言。

[Test]
public void MapTest()
{
    var a = new A 
    { 
        Id = "123",
        Name = "Name of A",
        SomeProperty = new LowLevelClass { Value = 42 } 
    }; 
    var expected = new B 
    { 
        Id = "123"
    };

    var actual = mapping.Map(a);

    actual.Should().BeEquivalentTo(expected);
}

上面的示例假定,B的默认构造函数不实例化其他属性,但如果确实如此,则创建预期的B实例并将其他属性设置为null

var expected = new B 
{ 
    Id = "123",
    Name = null,
    SomeProperty = null
};

var actual = mapping.Map(a);

actual.Should().BeEquivalentTo(expected);

答案 1 :(得分:0)

很抱歉,在NUnit的本机断言中没有办法做到这一点。您可以将逻辑封装在一个方法中,该方法获取属性名称列表并使用反射。这就是我在类似情况下的表现。

打包逻辑的一种巧妙方法是编写

Assert.That(b, Has.Properties("Prop1", "Prop2", ...).Null;

其中Has.Properties将使用所有命名属性值的列表替换参数b,然后对其应用以下约束。

这似乎不足以包含在NUnit本身中,但可以作为自定义约束。

另一种方法是写

Assert.That(b.Properties("Prop1", "Prop2"...), Is.All.Null);

其中,Properties是object的扩展方法。

第三个选项(可能是最简单的)是扩展NUnit的ListMapper