IntroductionThe intention of NUnitEx is write short assertions where the Visual-Studio IDE intellisense is "your friend". AssertionsThe entry point of each assertion is the method Should() or its override Should(string) where the parameter is the title of the assertion (the message in NUnit terminology). After Should(). the intellisense become "your friend". In general, each assertion allow negation (Should().Not.) and chain through .And.. Negation and .And. chain are available only where it has sense. Where the assertion imply a cast, the additional property And.ValueOf. is available to begin a new assertion based on one of the properties of casted original actual value (examples are available below). Boolean Assertionsbool actual;
...
actual.Should().Be.True();
actual.Should().Be.False();
Boolean assertion not allow negation nor chain. Object instance Assertionsobject actual;
...
actual.Should().Be.EqualTo(something);
actual.Should().Be.Null();
actual.Should().Be.SameInstanceAs(something);
actual.Should().Be.InstanceOf<SomeClass>();
actual.Should().Be.OfType<SomeClass>();
actual.Should().Be.AssignableFrom<SomeClass>();
actual.Should().Be.AssignableTo<SomeClass>();
actual.Should().Be.BinarySerializable();
actual.Should().Be.XmlSerializable(); Examples with negationsomething.Should().Not.Be.EqualTo(new object());
something.Should().Not.Be.Null(); Examples with chainvar something = new object();
something.Should()
.Not.Be.Null()
.And
.Not.Be.EqualTo(new object()); Example ValueOfvar instanceOfClass = new InheritedClass();
instanceOfClass.Should()
.Be.AssignableTo<BaseClass>()
.And.Be.OfType<InheritedClass>()
.And.ValueOf.StringProperty
.Should().Be.Null();After the assertion Be.OfType<InheritedClass>() we know which is the concrete type of the variable instanceOfClass so we can begin a new assertion based on one of the properties of instanceOfClass (see .And.ValueOf.StringProperty.Should().Be.Null()). Primitive struct types Assertionsvar minvalue = short.MinValue;
var maxvalue = short.MaxValue;
minvalue.Should().Be.LessThan(maxvalue);
minvalue.Should().Be.LessThanOrEqualTo(minvalue + 1);
maxvalue.Should().Be.GreaterThan(minvalue);
maxvalue.Should().Be.GreaterThanOrEqualTo(maxvalue - 1);
minvalue.Should().Be.EqualTo(minvalue);
minvalue.Should().Be.IncludedIn(minvalue, maxvalue);
For Nullable<T> int? nullable= null;
nullable.Should().Not.Have.Value(); Examples with negation and chain5.Should().Be.GreaterThan(3).And.Not.EqualTo(4);
1.Should().Not.Be.GreaterThan(3).And.Not.EqualTo(4); String Assertionsstring actual;
...
actual.Should().Be.EqualTo("a");
actual.Should().Be.Empty();
actual.Should().Be.Null();
actual.Should().Be.NullOrEmpty();
actual.Should().Contain("some");
actual.Should().StartWith("some");
actual.Should().EndWith("ing");
actual.Should().Match("ome[tT]h");
var re = new Regex("a.b", RegexOptions.Singleline | RegexOptions.IgnoreCase);
"a\nb".Should().Match(re);
Examples with negation and chainstring something = "something";
something.Should()
.StartWith("so")
.And
.EndWith("ing")
.And
.Contain("meth");
something.Should()
.StartWith("so")
.And
.EndWith("ing")
.And
.Not.Contain("body");
something.Should()
.Not.StartWith("ing")
.And
.Not.EndWith("so")
.And
.Not.Contain("body");IEnumerable<T> AssertionsIEnumerable<int> actual;
...
actual.Should().Contain(expected);
actual.Should().Have.SameValuesAs(new[] { 3, 2, 1 });
actual.Should().Have.SameValuesAs(3, 2, 1 );
actual.Should().Have.UniqueValues();
actual.Should().Have.SameSequenceAs(new[] { 1, 2, 3 });
actual.Should().Have.SameSequenceAs(1, 2, 3 );
actual.Should().Have.Count.EqualTo(3)
actual.Should().Be.Null();
actual.Should().Be.Empty();
actual.Should().Be.SameInstanceAs(expected);
actual.Should().Be.SubsetOf(new[] { 1, 2, 3, 4 });
actual.Should().Be.SubsetOf(1, 2, 3, 4 );
actual.Should().Be.Ordered();
actual.Should().Be.OrderedAscending();
actual.Should().Be.OrderedDescending();Examples with negation and chainvar ints = new[] { 1, 2, 3 };
ints.Should()
.Have.SameSequenceAs(new[] { 1, 2, 3 })
.And
.Not.Have.SameSequenceAs(new[] { 3, 2, 1 })
.And
.Not.Be.Null()
.And
.Not.Be.Empty();
ints.Should().Contain(2).And.Not.Contain(4);
ints.Should().Contain(3).And.Not.Have.Count.LessThan(2);Action AssertionsThe Action is basically to check a possible Exception executing the Action. Here the ValueOf come in play again. (new Action(() => new AClass(null)))
.Should().Throw<ArgumentNullException>()
.And.
ValueOf.ParamName
.Should().Be.EqualTo("obj");or (new Action(() => new object())).Should().NotThrow<ArgumentNullException>(); The same assertion, using NUnit classic Assert mixed with NUnitEx, look like: Assert.Throws<ArgumentNullException>(() => new AClass(null))
.ParamName.Should().Be.EqualTo("obj");About Exceptions, NUnitEx offers two additional useful extensions : exception.InnerExceptions() and exception.Exceptions(). - exception.InnerExceptions() return a IEnumerable<Exception> of all Inner Exceptions.
- exception.Exceptions() return a IEnumerable<Exception> including the root Exception.
As result giving a class like this: public class SillyClass
{
public SillyClass(object obj)
{
if (obj == null)
{
throw new ArgumentException("mess",
new ArgumentNullException("mess null",
new ArgumentOutOfRangeException("obj")));
}
}
}you can write tests like these: (new Action(() => new SillyClass(null))
.Should().Throw<ArgumentException>()
.And.ValueOf.InnerExceptions()
.OfType<ArgumentOutOfRangeException>().First()
.ParamName.Should().Be.EqualTo("obj");
(new Action(() => new SillyClass(null))
.Should().Throw<ArgumentException>()
.And.ValueOf.InnerExceptions().Select(e => e.GetType())
.Should().Contain(typeof(ArgumentOutOfRangeException));
(new Action(() => new SillyClass(null))
.Should().Throw<ArgumentException>()
.And.ValueOf.InnerException
.Should().Be.OfType<ArgumentNullException>()
.And.ValueOf.Message.Should().Be.EqualTo("mess null");Examples with negation(new Action(() => new object())).Should().NotThrow<ArgumentNullException>(); Note that the negation does not allow chain. Type Assertionsprivate class B {}
[Serializable]
private class D1 : B { }
private class D2 : D1 { }
typeof(D1).Should().Be.EqualTo<D1>();
typeof(D1).Should().Be.SubClassOf<B>();
typeof(D1).Should().Be.AssignableFrom<D2>();
typeof(D1).Should().Have.Attribute<SerializableAttribute>();
Type t = null;
t.Should().Be.Null();
Examples with negationtypeof(D1).Should().Not.Be.EqualTo<B>();
typeof(D1).Should().Not.Be.SubClassOf<D2>();
typeof(D1).Should().Not.Be.AssignableFrom<B>();
typeof(D1).Should().Not.Be.Null();
typeof(B).Should().Not.Have.Attribute<SerializableAttribute>(); Lambda/LINQ based AssertionsFor this kind of assertion there only few words to say because they are "simply" pure .NET language based assertion. Some examples may be are more clear than many words 1.Should().Satisfy(x => x == 1 || x == 2);
1.Should().Satisfy(x => x > 0);
1.Should().Satisfy(x => 2 > x);
const int y = 2;
const int z = 4;
4.Should().Satisfy(x => x == y * y);
2.Should().Satisfy(x => x == z / y);
"1".Should().Satisfy(x => x == 1.ToString());
var y = 2;
new[] { 1, 2 }.Should().Satisfy(x => x.Contains(y));
var y = new[] { 1, 2 };
var z = new[] { 2, 1 };
1.Should().Satisfy(x => x == y[0] && x == z[1]);and using LINQ extensions new[] { 1, 2 }.Should().Satisfy(x => x.SequenceEqual(new[] { 1, 2 }));To be valid, an assertion using Should().Satisfy(expression), must include the actual parameter in one of the two sides of the expression. Others Extensions useful for testsSystem.Object ExtensionsFieldValue<T>Allow access to a private field where a public property is not available. public class A
{
private int oneField;
public void Configure()
{
oneField = 5;
}
}
// The test based on the class
var a = new A();
a.FieldValue<int>("oneField").Should().Be.EqualTo(0);
a.Configure();
a.FieldValue<int>("oneField").Should().Be.EqualTo(5);
|
gRtfydtesyzzzzrizzyzzzdzzzizzzfizuzzzz