调整字符串生成器以避免在 C# 中使用 FsCheck.Xunit 的“\0”

Adjust string generator to avoid "\0" with FsCheck.Xunit in C#

在使用字符串输入创建 FsCheck.Xunit 单元测试时,我正在努力解决频繁出现的包含“\0”的字符串,我相信它会输入 C 库并导致字符串 t运行cation . FsCheck 经常创建包含“\0”的字符串,如果您 运行 下面的测试,您会发现。

调整字符串生成器以避免字符串包含“\0”的最简单方法是什么?我在多个测试中需要这种行为,并且我正在使用 .NET Core。

BR,马克

public class NewTests
{

    [Property(Verbose = true)]
    public Property Test1(string myString)
    {
        return (!myString.Contains("[=11=]")).ToProperty();
    }

}

最简单的方法是在测试中将其过滤掉,例如使用辅助方法。但是请注意,字符串本身也可以为空。

如果您想要可以是 null 但不包含 null 个字符的字符串:

[Property]
public bool TestIt(StringNoNulls s)
{
    return s.Item == null || !s.Item.Contains("[=10=]");
}

如果你想要非空字符串:

[Property]
public bool TestIt(NonNull<string> s)
{
    return s != null;
}

如果你想要两者,我没有开箱即用的东西!但是,您可以执行以下操作:

public class CustomArbs
{
    public static Arbitrary<string> ReallyNoNullsAnywhere()
    {
        return Arb.Default.String().Filter(s => s != null && !s.Contains("[=12=]"));
    }
}

[Property(Arbitrary = new[] { typeof(CustomArbs) })]
public bool TestIt(string s)
{
    return s != null && !s.Contains("[=12=]");
}

还有 PropertiesAttribute,您可以将其放在 class 上以覆盖 class 中所有属性上特定类型集的所有任意实例,因此您不必必须在每个测试方法上添加 Arbitrary 参数。

我最终经常使用的模式不是覆盖 Arbitrary<string> 实例本身,而是创建一个包装器类型,这样在签名中就可以清楚地看到我得到的字符串类型:

public class AntiNullString
{
    public string Get { get; }

    public AntiNullString(string s)
    {
        Get = s;
    }
}

public class CustomArbs
{
    public static Arbitrary<AntiNullString> ReallyNoNullsAnywhere()
    {
        return Arb.Default.String()
            .Filter(s => s != null && !s.Contains("[=13=]"))
            .Convert(s => new AntiNullString(s), ans => ans.Get);
    }
}

[Property(Arbitrary = new[] { typeof(CustomArbs) })]
public bool TestIt(AntiNullString s)
{
    return s.Get != null && !s.Get.Contains("[=13=]");
}