[英]Unit Testing a function dealing with database records
單元測試應該只測試一個函數的邏輯,並且應該“模擬”該函數中使用的數據。 我想知道我們如何將以下函數與“模擬”數據結合起來? 或者即使它是正確的方法。 函數簽名是
public String doSomething(int firstId, int secondId, int count){
//this function looks in a table e.g. C which has foreign keys from table A, and B
//if firstId and secondId exist in db table C return "already-exists"
//if count < a_column_value_in_table_C return "not-allow"
// else return "success"
}
firstId
和secondId
是形成兩個不同表的外鍵。 現在,我們如何在以下方面對這個函數進行單元測試: 1. 單元測試應該如何設計,以便能夠測試函數中的 3 個場景 2. 我們如何為這個單元測試准備數據,因為它將需要來自兩個不同表的外鍵。
您應該使用 Solid 原則中的依賴注入。 doSomething 方法的所有者類應該注入一些 Repository 或 DAO 等。
在您的單元測試中,您應該模擬存儲庫方法。
例如,假設您的 doSomething 方法調用存儲庫的 findById(...) 方法。 您應該通過所需的輸出模擬 findById 方法,並只測試流程的邏輯部分。
我通常使用 getById 和 getAll 函數創建存儲庫接口。 出於測試目的,我創建了一個 inmemory-repository,對於生產,我使用了 database-repository。
這里有一個例子:
public interface Repository<T> {
public T getById(int Id);
public List<T> getAll();
}
public InmemoryRepository implements Repository<User> {
List<User> database = new ArrayList<>(); //with some data
public List<User> getAll() {
return database;
}
public User get(int Id) {
return database.stream().filter(x -> x.Id = Id).collect(Collectors.asList());
}
}
在您的函數中,您注入此存儲庫,以便您可以通過以下方式訪問數據庫:
public String doSomething(int firstId, int secondId, int count, Repository<User> repo){};
您可以使用一些測試數據庫或內存數據庫(如 HSQLDB)。 在測試之前用一些測試數據填充它(在方法注釋@BeforeClass
或在測試數據源初始化期間,如果你使用 Spring)。 然后對傳遞准備好的數據的所有場景執行測試。 在用@AfterClass
注釋的方法中清理測試數據庫中的數據。
如果您在 XML 配置中使用 Spring 和配置來測試 dataSource 可能如下所示:
<jdbc:embedded-database id="dataSource" type="HSQL" >
<jdbc:script location="scripts/ddl/*"/> <!-- create tables -->
<jdbc:script location="scripts/dml/*"/> <!-- populate test data -->
</jdbc:embedded-database>
你不應該設計一個單元測試來匹配所有的情況。 為每種情況創建不同的單元測試。
您需要模擬訪問數據庫的存儲庫或類,以便它不會在數據庫中執行,而是返回您在單元測試中預先確定的結果集。 有模擬庫,這使您的工作非常容易。 如果代碼只是執行一個查詢或過程並返回結果,那么為它編寫單元測試沒有多大價值,在這種情況下編寫集成測試應該就足夠了。
PS:Emre Savcı,依賴注入不是一個可靠的原則,依賴倒置是。 他們根本沒有關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.