Nowa składnia asercji w NUnit 2.4
Podstawą każdego testu jednostkowego jest asercja, czyli polecenie sprawdzenia, czy testowany obiekt spełnia pewną własność. W wersjach NUnit wcześniejszych niż linia 2.4 podstawowym sposobem do wyrażenia asercji w kodzie testu było użycie statycznych metod klasy Assert z przestrzeni nazw NUnit.Framework. Na przykład:
[Test]
public void StringBuilderShouldGlueStringsTogether() {
StringBuilder builder = new StringBuilder();
builder.Append("NUnit ");
builder.Append("2.4.7");
Assert.AreEqual("NUnit 2.4.7", builder.ToString());
}
Podstawowym i najczęściej chyba używanym typem asercji jest sprawdzenie, czy dwie wartości są sobie równe (metoda Assert.AreEqual), tak jak w powyższym przykładzie. Klasa Assert dostarcza jeszcze wielu innych metod, które pozwalają w łatwy sposób sprawdzać własności obiektów. Na przykład:
[Test]
public void MathSinShouldReturnValuesGreaterOrEqualToMinusOne() {
// Nigdy nie powinniśmy losować wartości w testach!
Random generator = new Random();
double argument = generator.NextDouble();
double sin = Math.Sin(argument);
Assert.GreaterOrEqual(sin, -1.0);
}
Oprócz klasy Assert mamy do dyspozycji także bardziej wyspecjalizowane klasy:
Klasy te umożliwiają łatwe sprawdzanie bardziej wyszukanych własności, takich jak na przykład to, czy kolekcja zawiera jakiś element:
[Test]
public void CollectionShouldContainItsElements() {
int[] integers = new int[] { 1, 2, 3, 4, 5 };
CollectionAssert.Contains(integers, 3);
}
W wersji 2.4 biblioteki NUnit wprowadzono nowy sposób wyrażania asercji oparty o
ograniczenia (ang.
constraint model). W tym modelu do wyrażenia każdej asercji używamy jednej i tej samej metody Assert.That, a logika związana ze sprawdzeniem własności testowanego obiektu jest zaimplementowana w odpowiednim obiekcie, który przekazujemy jako jeden z parametrów metody Assert.That. Obiekty te noszą nazwę
ograniczeń. Na przykład:
[Test]
public void StringBuilderShouldGlueStringsTogether() {
StringBuilder builder = new StringBuilder();
builder.Append("NUnit ");
builder.Append("2.4.7");
Assert.That(
builder.ToString(),
new EqualConstraint("NUnit 2.4.7"));
}
Obiekt klasy EqualConstraint (z przestrzeni nazw NUnit.Framework.Constraints) implementuje logikę zawartą poprzednio w kodzie metody Assert.AreEqual. W czym ten sposób wyrażania asercji jest lepszy od poprzedniego? Siła nowego modelu leży w klasach pomocniczych zawartch w przestrzeni nazw NUnit.Framework.SyntaxHelpers, które pozwalają w łatwy sposób tworzyć i łączyć obiekty implementujące ograniczenia. Klasy pomocnicze, o których tutaj mowa, stanowią
fluent interface (
opisany przez Martina Fowlera), co czyni API do tworzenia obiektów implementujących ograniczenia bardzo czytelnym i intuicyjnym w użyciu. Niech przykłady mówią same za siebie:
[Test]
public void StringBuilderShouldGlueStringsTogether() {
StringBuilder builder = new StringBuilder();
builder.Append("NUnit ");
builder.Append("2.4.7");
Assert.That(builder.ToString(), Is.EqualTo("NUnit 2.4.7"));
}
[Test]
public void MathSinShouldReturnValuesGreaterOrEqualToMinusOne() {
// Nigdy nie powinniśmy losować wartości w testach!
Random generator = new Random();
double argument = generator.NextDouble();
double sin = Math.Sin(argument);
Assert.That(sin, Is.GreaterThanOrEqualTo(-1.0));
}
[Test]
public void CollectionShouldContainItsElements() {
int[] integers = new int[] { 1, 2, 3, 4, 5 };
Assert.That(integers, Has.Member(3));
}
Miłego testowania!