Ho riflettuto sulle best practice del test unitario e ho riscontrato la regola one assertion per unit test . Riesco a vedere dove questa idea potrebbe aiutare a isolare parti di operazioni complesse o di verifica quando si dispone di codice in questo modo:
private Place place;
@Test
public void test_whiteHouse(){
place = new place(KnownPlaces.WHITEHOUSE);
assertEquals("1600 Pennsylvania Avenue", place.getAddress());
assertEquals("Washington", place.getCity());
assertEquals("DC", place.getState());
}
Vedo dove vorresti in genere dividerlo in test più piccoli come questo:
private Place place;
@Before
public void setUp(){
place = new place(KnownPlaces.WHITEHOUSE);
}
@Test
public void test_whiteHouse_street(){
assertEquals("1600 Pennsylvania Avenue", place.getAddress());
}
@Test
public void test_whiteHouse_city(){
assertEquals("Washington", place.getCity());
}
@Test
public void test_whiteHouse_state(){
assertEquals("DC", place.getState());
}
Tuttavia, se sto testando un setter, il codice potrebbe apparire come questo:
@Test
public void test_place_setCity(){
String newCity = "timbuktu";
Place place = new Place();
place.setCity(newCity);
assertEquals(newCity, place.getCity());
}
Il test funzionerà correttamente, ma se c'è una configurazione condivisa, sto facendo delle ipotesi sullo stato iniziale. Quale sarebbe il rovescio della medaglia su come eseguire un controllo sullo stato iniziale qualcosa come:
@Test
public void test_place_setCity(){
String newCity = "timbuktu";
Place place = new Place();
assertFalse(place.getCity().equals(newCity));
place.setCity(newCity);
assertEquals(newCity, place.getCity());
}
Questo controllo verificherebbe che il metodo setter effettivamente modificato qualcosa verificando lo stato iniziale fosse diverso dallo stato finale. In caso contrario, un cambiamento o un malfunzionamento in un costruttore o in un metodo di installazione potrebbero rendere il test inefficace. Ci sono degli svantaggi di violare la regola di asserzione per vincolo in questo modo?