Durante la scrittura di unit test per classi (specialmente quando si utilizza DI e mock) ultimamente ho spesso trovato utile strutturare i miei test su una classe che esegue effettivamente i test e una responsabile per l'installazione, che mi aiuta a mantenere i miei test puliti e leggibili .
La classe di test avrà il seguente aspetto
public class MyFooBarTests
{
MyFooBarTestFixture _testFixture = new MyFooBarTestFixture();
[SetUp]
public void SetUp()
{
_testFixture.SetUp();
}
[Test]
public void ATest()
{
_testFixture.GivenRepositoryReturnsPi();
_testFixture.CallMyFancyMethod();
_testFixture.AssertQuxBaxIs(3.14159);
}
}
e quello che chiamo test fixture sarà simile a questo
internal class MyFooBarTestFixture
{
private Mock<IRepository> _repositoryMock;
private MyFooBar _cut;
public void SetUp()
{
SetUpRepositoryMock(); // elided
SetUpCut();
}
private void SetUpCut()
{
_cut = new MyFooBar(_repositoryMock.Object);
}
public void GivenRepositoryReturnsPi()
{
_repositoryMock.Setup(r => r.GetValue()).Returns(Math.PI);
}
public void CallMyFancyMethod()
{
_cut.MyFancyMethod();
}
public void AssertQuxBaxIsEqual(double expectedValue)
{
Assert.That(_cut.QuxBaz, Is.EqualTo(expectedValue)); // elided correct floating point comparison
}
}
Dal mio punto di vista, questa separazione è davvero utile. Quando osservi la classe dei test, è chiaro come cosa fanno i test, mentre i dettagli di come sono fatti sono nascosti e ben incapsulati nel dispositivo di prova. Il dispositivo di prova a sua volta ha metodi accurati e brevi.
Quali sono gli svantaggi di organizzare i miei test unitari in questo modo?
Alcuni pensieri:
- Sono consapevole che alcuni test richiederanno un trattamento speciale in questo paradigma
- Quando ci sono un bel po 'di mock, il dispositivo di test perderà la coesione, ma questo potrebbe essere uno spunto per il fatto che il componente in prova lo fa comunque molto
- L'emergere di questo schema è un segno che le mie classi stanno già facendo molto?
- Il test del nome potrebbe essere fuorviante? Da un punto di vista tecnico è ragionevole, poiché in altri campi ingegneristici è installato un apparecchio di prova per eseguire i test, ma non esegue necessariamente i test stessi. Ad ogni modo, nello sviluppo del software, il termine potrebbe sollevare aspettative non soddisfatte da ciò che chiamo test fixture.