Mettiamo di dover scrivere un test per una classe che utilizza un parametro di tipo enum e di voler testare la classe con ogni valore presente all'interno dell'enumerazione. Ad esempio:
La mia enumerazione è
public enum FooEnum
{
A,
B,
C
}
e questa la classe che la utilizza
public class Foo
{
private readonly FooEnum _item;
public Foo(FooEnum fooEnum)
{
_item = fooEnum;
}
public override string ToString()
{
return _item.ToString();
}
}
Utilizzando congiuntamente gli attributi RowTest e Row possiamo scrivere un test in questo modo:
[TestFixture]
public class FooEnumTest {
[RowTest]
[Row(FooEnum.A)]
[Row(FooEnum.B)]
[Row(FooEnum.C)]
public void FooEnumValues_WithRowTestAttribute(FooEnum item)
{
Foo foo =new Foo(item);
Assert.AreEqual(item.ToString(), foo.ToString());
}
}
così facendo il test viene eseguito per ogni elemento oggi contenuto nell'enumerazione. Pensando ad enumerazioni con molti elementi il codice è poco leggibile ma comunque funzionate.
Nel futuro però questo approccio può dimostrarsi poco "smart". Pensiamo al momento in cui viene aggiunto un altro valore all'enumerazione. Se qualcuno non si ricorda di aggiornare il test aggiungendo un attributo Row per il nuovo elemento dell'enumerazione il test non copre più tutti i valori della nostra enumerazione.
Per ovviare a questo problema fortunatamente con MbUnit abbiamo a disposizione attributo ad-hoc che si occupa autonomamente di eseguire il test per ognuno dei valori dell'enumerazione garantendoci così maggiore flessibilità nel caso in cui gli elementi all'interno dell'enumerazione cambino.
Questo il testo scritto utilizzando l'attributo UsingEnum
[TestFixture]
public class FooEnumTest {
[CombinatorialTestAttribute]
public void FooEnumValues_UsingEnumAttribute([UsingEnum(typeof (FooEnum))]FooEnum item)
{
Foo foo =new Foo(item);
Assert.AreEqual(item.ToString(), foo.ToString());
}
}
Mi perdonino i puristi del TDD perchè prima ho presentato la classe e poi il test ma questo approccio mi sembrava più semplice per la comprensione del risultato che volevamo ottenere tramite l'attributo UsingEnum. Prima viene sempre scritto il test poi il codice da testare ma anche i test possono essere oggetto di refactoring!