【问题标题】:Assert that all properties but some are null断言所有属性,但一些属性为空
【发布时间】:2018-11-22 15:27:22
【问题描述】:

我有映射方法,将模型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
}

【问题讨论】:

  • 嗯,我看到的唯一选项是使用Reflection,但我认为这并不能真正简化您的代码
  • 我有这个想法,但正如你所说,这不是我正在寻找的解决方案类型。
  • 你确定B类的所有属性都是静态的吗?
  • @Fabio,谢谢,这是一个错字。

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


【解决方案1】:

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

【讨论】:

  • 我不相信这可以解决上述问题,因为映射函数并未映射所有属性。
  • @Charlie,我创建了expected 实例,其中其他属性为null。所以actual 结果也应该有null。当然,在我的示例中,我假设 B 的默认构造函数不会实例化其他属性。
【解决方案2】:

很抱歉,在 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-15
    • 2018-09-21
    • 2022-01-17
    • 2022-03-31
    • 1970-01-01
    • 2016-06-21
    • 2021-12-16
    • 1970-01-01
    相关资源
    最近更新 更多