Ostatnimi czasy siedzę trochę w Spring Framework, frameworku dla Javy. Doszedłem do etapu testów i stwierdziłem, że godnym opisania będzie sposób testowania metod opartych o transakcje, gdyż ciekawym jest fakt iż wszystko co odbywa się w danych testach (dodawanie danych, edycja itd.) jest następnie cofane do wersji pierwotnej (wywoływany jest rollback na transakcji) i dzieje się to automatycznie.
Poniżej znajduje się przykładowa klasa wraz z metodami testującymi. Wszystko oparte jest na adnotacjach, więc nie ma problemu:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-config.xml"
public class UserAccountDaoImplTest {
@Resource
UserAccountDaoImpl userAccountDaoImpl;
@Test
@Transactional
public void testSaveUser() {
System.out.println("saveUser");
UserAccount transientInstance = new UserAccount();
transientInstance.setEmail("email@mail.con");
transientInstance.setEnabled(true);
userAccountDaoImpl.saveUser(transientInstance);
UserAccount userFromDb = userAccountDaoImpl.getByEmail("email@mail.con);
assertNotNull("User should be not null", userFromDb);
assertTrue("User should be enabled", userFromDb.isEnabled());
assertTrue("User should be non locked", userFromDb.isAccountNonLocked());
}
@Test(expected = ConstraintViolationException.class)
@Transactional
public void testSaveUserDuplicateEmail() {
System.out.println("saveUserDuplicateEmail");
UserAccount transientInstance = new UserAccount();
transientInstance.setEmail("michal@somedomain.pl");
userAccountDaoImpl.saveUser(transientInstance);
}
@Test
@NotTransactional
public void testGetUserById() {
System.out.println("getUserById");
long id = 1L;
UserAccount result = userAccountDaoImpl.getUserById(id);
assertNotNull("User with id " + id + " should be found", result);
assertEquals(new Long(id), result.getId()) id = 667L;
result = userAccountDaoImpl.getUserById(id);
assertNull("User with id " + id + " should not be found", result);
@Test(expected = UsernameNotFoundException.class)
@NotTransactional
public void testGetByEmailNoUser() {
System.out.println("getByEmailNoUser");
String email = "someone@gnail.con";
userAccountDaoImpl.getByEmail(email);
}
}
Początkowo inicjujemy kontekst springa (definiujemy która klasa się tym zajmie i dodajemy plik konfiguracyjny).
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:test-config.xml”)
Następnie musimy wstrzyknąć do testu instancję którą testujemy, wykorzystujemy do tego adnotację @Resource:
@Resource
UserAccountDaoImpl userAccountDaoImpl;
Nie będę tutaj opisywał adnotacji czystego JUnita, zwrócę jedynie uwagę na adnotacje potrzebne przy testowaniu danych opartych o DB. Tak więc mamy:
@Transactional – określa nam, że dana metoda korzysta z transakcji i ma być wykonany rollback
@NotTransactional – odwrotnie do tego wyżej
Dodatkowo, co nie zostało pokazane na powyższym przykładzie, możemy skorzystać z adnotacji @Rollback(false) jeżeli nie chcemy, aby wykonywany był rollback po wykonaniu testu.
Mam nadzieję, że powyższy (działający u mnie) przykład komuś się przyda. Ja chwilę spędziłem, zanim doprowadziłem go do porządku, choć okazało się to niezwykle proste (wynik końcowy)