The simplest possible way is to just filter it out inside your test, e.g. using a helper method. However note that string itself can also be null.
If you want strings that can be null
but contain no null
characters:
[Property]
public bool TestIt(StringNoNulls s)
{
return s.Item == null || !s.Item.Contains("\0");
}
If you want non-null strings:
[Property]
public bool TestIt(NonNull<string> s)
{
return s != null;
}
If you want both I have nothing out of the box! But, you can do something like:
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");
}
There's also PropertiesAttribute
which you can put on a class to override all Arbitrary instances of a particular set of types on all properties in that class, so you don't have to add the Arbitrary argument on each test method.
A pattern that I end up using often is not to override the Arbitrary<string>
instance itself, but make a wrapper type, so it then becomes clear in the signuature what sort of string I'm getting:
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");
}