【问题标题】:How to assert a default value of a property with FluentAssertions?如何使用 FluentAssertions 断言属性的默认值?
【发布时间】:2014-04-08 22:44:52
【问题描述】:

我有一个包含各种类型的字段/属性等的类:

public string SomeStringData;
public int? SomeNullableIntegerData;
public SomeDataClass SomeSpecificData;
public int SomeIntegerData;

在我的部分代码中,应该只填写SomeStringData,我想明确地测试一下。我使用FluentAssertions 并拥有

actual.SomeStringData.Should().Be("Whatever");

但是如何测试,没有其他元素没有被触及并且仍然具有它们的默认值?我当然可以:

actual.SomeNullableIntegerData.Should().NotHaveValue("Must have no value.");
actual.SomeDataClass.Should().BeNull("Must have no value.");
actual.SomeNullableIntegerData.Should().Be(0, "Must have no value.");

但是,如何更清楚地表达这些项目应该具有默认值?

例如使用虚构的BeDefault 运算符:

actual.SomeNullableIntegerData.Should().BeDefault("Must have no value.");
actual.SomeDataClass.Should().BeDefault("Must have no value.");
actual.SomeNullableIntegerData.Should().BeDefault("Must have no value.");

有这样的选择吗?

【问题讨论】:

    标签: c# unit-testing nunit default fluent-assertions


    【解决方案1】:

    我会创建扩展方法

    public static void ShouldHaveDefaultValue<T>(this T value)
    {
        if (!EqualityComparer<T>.Default.Equals(value, default(T)))
            throw new AssertionException("Must have default value.");
    }
    

    用法:

    actual.SomeNullableIntegerData.ShouldHaveDefaultValue();
    actual.SomeDataClass.ShouldHaveDefaultValue();
    actual.SomeIntegerData.ShouldHaveDefaultValue();
    

    用BeDefault() 扩展Should() 会很困难,因为有不同的Should() 扩展会返回不同的断言对象——BooleanAssertions、StringAssertions、GuidAssertions 等。所有这些断言类都没有具有可以扩展的通用基类。

    【讨论】:

    • 很好,我要试试这个。但是,我希望有一些已经内置的方法可以做到这一点。测试默认值不是很常见吗,还是只发生在我身上?
    • @Marcel 实际上测试默认值并不常见。通常您应该检查是否发生了值更改。这就像足球比赛评论:“球员A有球,球员B没有球,球员C没有球,球员D没有球。现在球员A将球传给球员B. 球员 B 有球,球员 A 没有球,球员 C 没有球……等等” 如果能获得更多关于您正在测试的代码的信息,那就太好了。如果只需要填充 SomeStringData,那么最好只返回字符串值而不是传递整个对象
    • 您通常只传递一个值是对的。但是,在我的情况下,业务决策是始终返回相同的完全成熟的对象,但仅根据用户的角色填充数据。现在我要断言,对于某些角色,只返回某些数据。
    • @Marcel 好吧,也考虑返回类似字典的东西。它很容易断言返回的条目计数并检查它们的值。根据用户的角色用数据填充这些字典。您还可以创建自定义词典。我不建议使用部分填充的课程
    • @SergeyBerezovskiy 实际上,所有这些断言类都共享一个共同的基类。这是ReferenceTypeAssertions 类(虽然我很确定我会在 v3.0 中重命名它)。
    【解决方案2】:

    我会预先捕获以前的值,并断言在执行任何应该进行更改的内容之后,这些值仍然具有它们的默认值。提议的BeDefault 方法永远不能对“默认”做出任何假设。

    【讨论】:

    • 可以,因为默认情况下我的意思是该类型的默认值,例如整数的 0(零)。
    • 哦,那我误会你了。我以为你的意思是它应该有它的原始价值。在这种情况下, BeDefault() 确实有意义。如果你愿意,你可以在 GitHub 上提出这个建议,以便我可以将它包含在 v3.0 中。
    猜你喜欢
    • 2017-09-18
    • 2022-01-17
    • 2022-05-26
    • 2020-02-21
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 2019-07-09
    相关资源
    最近更新 更多