【问题标题】:How to exclude null value when using FsCheck Property attribute?使用 FsCheck 属性时如何排除空值?
【发布时间】:2016-12-08 00:42:16
【问题描述】:

我需要编写一个简单的方法来接收参数(例如string)并执行某项操作。通常我会做两个测试。第一个是guard clause。第二个将验证 预期 行为(为简单起见,该方法不应失败):

[Fact]
public void DoSmth_WithNull_Throws()
{
    var sut = new Sut();
    Assert.Throws<ArgumentNullException>(() =>
        sut.DoSmth(null));
}

[Fact]
public void DoSmth_WithValidString_DoesNotThrow()
{
    var s = "123";
    var sut = new Sut();
    sut.DoSmth(s); // does not throw
}

public class Sut
{
    public void DoSmth(string s)
    {
        if (s == null)
            throw new ArgumentNullException();

        // do smth important here
    }
}

当我尝试利用 FsCheck [Property] 属性生成随机数据时,null 和许多其他随机值被传递给测试,这在某些时候会导致 NRE:

[Property]
public void DoSmth_WithValidString_DoesNotThrow(string s)
{
    var sut = new Sut();
    sut.DoSmth(s); // throws ArgumentNullException after 'x' tests
}

我意识到这就是 FsCheck 的全部想法,即生成大量随机数据以涵盖不同的情况,这绝对很棒。

是否有任何优雅的方式来配置[Property] 属性以排除不想要的 值? (在这个特定的测试中,null)。

【问题讨论】:

    标签: tdd xunit.net fscheck


    【解决方案1】:

    FsCheck 有一些内置类型可用于指示特定行为,例如,引用类型值不应为空。其中之一是NonNull&lt;'a&gt;。如果您要求其中之一,而不是要求原始字符串,您将不会得到空值。

    在 F# 中,您可以将其解构为函数参数:

    [<Property>]
    let DoSmth_WithValidString_DoesNotThrow (NonNull s) = // s is already a string here...
        let sut = Sut ()
        sut.DoSmth s // Use your favourite assertion library here...
    }
    

    我认为在 C# 中,它应该看起来像这样,但我没有尝试过:

    [Property]
    public void DoSmth_WithValidString_DoesNotThrow(NonNull<string> s)
    {
        var sut = new Sut();
        sut.DoSmth(s.Get); // throws ArgumentNullException after 'x' tests
    }
    

    【讨论】:

    • 很遗憾,C# 没有 [NotNull] 属性(至少我在源代码中找不到)。
    • @SergeyShushlyapin 这不是属性,而是类型。它在FsCheck 中定义,而不是FsCheck.Xunit
    • 啊,是No_n_Null!我在找No_t_Null,我的错,对不起。是的,它有效。谢谢马克!
    猜你喜欢
    • 2010-12-04
    • 2022-01-17
    • 2014-08-10
    • 1970-01-01
    • 2020-09-28
    • 2011-12-14
    • 2020-03-27
    • 1970-01-01
    • 2017-10-25
    相关资源
    最近更新 更多