Birim testi için 'gerçek' bir veritabanı kullanmayla ilgili sorun, testlerin kurulumu, alınması ve yalıtılmasıdır. Tamamen yeni bir MySQL veritabanını döndürmek ve sadece bir birim test için tablolar ve veriler oluşturmak istemezsiniz. Bununla ilgili problemler veritabanının dış doğası ile ilgilidir ve test veritabanınız kapalı, birim testleriniz başarısız olur. Ayrıca, test için benzersiz bir veritabanına sahip olduğunuzdan emin olmayla ilgili sorunlar da vardır. Üstesinden gelinebilirler, ancak daha basit bir cevap var.
Veritabanını taşımak bir seçenektir ancak çalıştırılan gerçek sorguları test etmez. DAO'daki verilerin sistemden düzgün bir şekilde geçtiğinden emin olmak istediğinizde çok daha basit bir çözüm olarak kullanılabilir. Ancak DAO'nun kendisini test etmek için DAO'nun arkasında bir şeye ihtiyacınız var, veriler var ve sorgular düzgün çalışıyor.
Yapılacak ilk şey bir bellek içi veritabanı kullanmaktır. HyperSQL bunun için mükemmel bir seçimdir çünkü başka bir veritabanının lehçesini taklit etme yeteneğine sahiptir - böylece veritabanları arasındaki küçük farklar aynı kalır (veri türleri, işlevler ve benzerleri). hsqldb ayrıca birim testi için bazı güzel özelliklere sahiptir.
db.url=jdbc:hsqldb:file:src/test/resources/testData;shutdown=true;
Bu, veritabanının durumunu (tablolar, ilk veriler) testData
dosyadan yükler. shutdown=true
son bağlantı kapatıldığında veritabanını otomatik olarak kapatır.
Bağımlılık enjeksiyonu kullanarak , birim testlerinin , üretimin (veya testin veya yerelin) oluşturduklarından farklı bir veritabanı seçmesini sağlayın.
DAO'nuz daha sonra veritabanına karşı testler başlatabileceğiniz enjekte edilmiş veritabanını kullanır.
Birim testleri daha sonra aşağıdaki gibi görünecektir (kısalık için dahil olmayan sıkıcı şeyler demet):
@Before
public void setUpDB() {
DBConnection connection = new DBConnection();
try {
conn = connection.getDBConnection();
insert = conn.prepareStatement("INSERT INTO data (txt, ts, active) VALUES (?, ?, ?)");
} catch (SQLException e) {
e.printStackTrace();
fail("Error instantiating database table: " + e.getMessage());
}
}
@After
public void tearDown() {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void addData(String txt, Timestamp ts, boolean active) throws Exception {
insert.setString(1, txt);
insert.setTimestamp(2, ts);
insert.setBoolean(3, active);
insert.execute();
}
@Test
public void testGetData() throws Exception {
// load data
Calendar time = Calendar.getInstance();
long now = time.getTimeInMillis();
long then1h = now - (60 * 60 * 1000); // one hour ago
long then2m = now - (60 * 1000 * 2); // two minutes ago
addData("active_foo", new Timestamp(then1h), true); // active but old
addData("inactive_bar", new Timestamp(then1h), false); // inactive and old
addData("active_quz", new Timestamp(then2m), true); // active and new
addData("inactive_baz", new Timestamp(then2m), false); // inactive and new
DataAccess dao = new DataAccess();
int count = 0;
for (Data data : dao.getData()) {
count++;
assertTrue(data.getTxt().startsWith("active"));
}
assertEquals("got back " + count + " rows instead of 1", count, 1);
}
Ve böylece, DAO'yu çağıran ve test süresince var olan bir anında veritabanında kurulan verileri kullanan bir birim testiniz var. Çalışmadan önce harici kaynaklar veya veritabanının durumu hakkında endişelenmenize veya bilinen bir duruma geri yüklemenize gerek yoktur (iyi bilinen 'bilinen durum' geri döndürülmesi önemsizdir 'yoktur').
DBUnit , veritabanı kurma, tablolar oluşturma ve veri yükleme daha basit bir süreç tarif ne yapabilirim. Gerçek veritabanını herhangi bir nedenden dolayı kullanmanız gerekiyorsa, bu kullanmak için çok daha iyi bir araçtır.
Yukarıdaki kod github üzerinde TestingWithHsqldb kavramının kanıtı için yazdığım bir maven projesinin bir parçasıdır