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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-config.xml"
public class UserAccountDaoImplTest {
@Resource
UserAccountDaoImpl userAccountDao;
@Test
@Transactional
public void testSaveUser() {
UserAccount transientInstance = new UserAccount();
transientInstance.setEmail("email@mail.con");
transientInstance.setEnabled(true);
userAccountDao.saveUser(transientInstance);
UserAccount userFromDb = userAccountDao.getByEmail("email@mail.con);
assertNotNull("User should be not null", userFromDb);
assertTrue("User should be enabled", userFromDb.isEnabled());
assertTrue("User should no be locked", userFromDb.isAccountNonLocked());
}
@Test(expected = ConstraintViolationException.class)
@Transactional
public void testSaveUserDuplicateEmail() {
System.out.println("saveUserDuplicateEmail");
UserAccount transientInstance = new UserAccount();
transientInstance.setEmail("michal@somedomain.pl");
userAccountDao.saveUser(transientInstance);
}
@Test
@NotTransactional
public void testGetUserById() {
long id = 1L;
UserAccount result = userAccountDao.getUserById(id);
assertNotNull("User with id " + id + " should be found", result);
assertEquals(new Long(id), result.getId()) id = 667L;
result = userAccountDao.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";
userAccountDao.getByEmail(email);
}
}
|
Początkowo inicjujemy kontekst springa (definiujemy która klasa się tym zajmie i dodajemy plik konfiguracyjny).
1
2
|
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:test-config.xml”)
|
Następnie musimy wstrzyknąć do testu instancję którą testujemy, wykorzystujemy do tego adnotację @Resource:
5
6
|
@Resource
UserAccountDaoImpl userAccountDao;
|
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),