Настройте генератор строк, чтобы избежать "\ 0" с помощью FsCheck.Xunit в C# - PullRequest
1 голос
/ 19 апреля 2020

При создании модульного теста FsCheck.Xunit со строковым вводом я сталкиваюсь с частыми вхождениями строк, содержащих «\ 0», которые, я полагаю, передаются в библиотеку C и приводят к усечению строки. Строки, содержащие "\ 0", часто создаются FsCheck, как вы обнаружите, если будете запускать тест, описанный ниже.

Какой самый простой способ настроить генератор строк, чтобы избежать строк, содержащих "\ 0"? Мне нужно это поведение в нескольких тестах, и я использую. NET Core.

BR, Марк

public class NewTests
{

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

}

1 Ответ

0 голосов
/ 23 апреля 2020

Самый простой способ - просто отфильтровать его внутри теста, например, с помощью вспомогательного метода. Однако обратите внимание, что сама строка также может быть нулевой.

Если вы хотите строки, которые могут быть null, но не содержат null символов:

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

Если вы хотите ненулевые строки :

[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("\0"));
    }
}

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

Также есть PropertiesAttribute, который вы можете поместить в класс для переопределения всех произвольных экземпляров определенного набора типов во всех свойствах этого класса, поэтому Не нужно добавлять аргумент 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("\0"))
            .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("\0");
}
...