Unit-Tests Teil 2: Integrationstests
Im Gegensatz zu Mocktests beschränkt sich ein Integrationstest nicht auf die JVM, sondern involviert auch Fremdsysteme wie Datenbanken, LDAPs oder Webservices. Ein Integrationstest ist auf immer gleichbleibende Testdaten im Fremdsystem angewiesen, muss aber ggf. auch den schreibenden Zugriff testen. Hier bieten sich Transaktionen an: Jede Testmethode läuft in einer eigenen Transaktion, die unabhängig vom Testergebnis immer wieder zurückgerollt wird. Somit bleibt das Fremdsystem in einem definierten Zustand. Dennoch sollten Integrationstests nicht auf den späteren Liveinstanzen ausgeführt werden, sondern immer auf dedizierte Testinstanzen. Allerdings sollte sichergestellt sein, dass die Test- und Liveinstanzen sich gleich verhalten.
Integrationstests bieten sich insbesondere für Dao-Klassen an, da hier der Zugriffscode für Fremdsysteme gekapselt wird. Gute Unterstützung bietet hier das Spring Framework mit den Annotationen @RunWith, @Transactional und @TransactionalConfiguration.
Beispiel-Code:
- @ContextConfiguration(locations = { "/applicationContext-test-jdbc-ldap-transactional.xml" })
- @RunWith(SpringJUnit4ClassRunner.class)
- @Transactional
- @TransactionConfiguration(defaultRollback = true)
- public class LdapUserDaoImplIntegrationTest
- {
- ...
- @Test
- public void createUser()
- {
- // create the user
- LdapUser ldapUser = createLdapUserPeterMueller();
- MutableLdapUserIdentity identity = ldapUser.getIdentity();
- // method under test
- ldapUserDaoImpl.createUser(ldapUser);
- LdapUser testUser = ldapUserDaoImpl.getLdapUserBySamAccountName(id);
- Assert.assertNotNull("user should now exist in ldap.", testUser);
- // test more
- }
- }
Vorteile:
- Das konkrete Verhalten eines Fremdsystems (z.B. Active Directory, oder einer MSSQL) kann abgeprüft werden.
- Fremde Webservices können automatisiert auf ihre Konsistenz geprüft werden.
Mögliche Stolperfallen:
- Integrationstests laufen nicht offline. Bei Mavenprojekten sollten sie für die Offline-Entwicklung abgeschaltet werden, da sonst der Build scheitert. Dies kann durch ein eigenes “mobile”-Profil in Kombination mit dem maven-sunfire-plugin sichergestellt werden.
- Die Testausführung dauert bei Integrationstest im Vergleich zu “normalen” JUnit-Tests wesentlich länger. Bei steigender Anzahl von länger laufenden Tests ist ein kompletter Durchlauf der Tests auf den Entwicklungsmaschinen nicht mehr sinnvoll.