gpt4 book ai didi

Java 解耦数据库操作代码并使其可测试

转载 作者:搜寻专家 更新时间:2023-11-01 01:26:10 25 4
gpt4 key购买 nike

我想为以下方法编写一个测试:

public void addItem(Item item) {

items.add(0, item);
DatabaseHelper.getInstance().writeOneItem(item);
}

该类称为 ItemManager,它的职责是管理用户可以保存到列表或从列表中删除的项目。它应该与保存列表中项目的 Sqlite 数据库保持同步。

DatabaseHelper (ormlite) 未使用 init(Context context) 启动时(这通常在我的 Andoid 应用程序启动时出现,但在我的测试中未完成),它的 getInstance() 方法将返回 null,上面的方法执行将崩溃。

我应该在这里做什么?我可以从我的测试中调用 init(Context context) 或检查 DatabaseManager.getInstance() 是否为空,然后再调用它。但这似乎更像是一种解决方法。在我看来,我不应该在此方法中执行任何数据库操作,而是应尽可能将 ItemManager 与数据库分开。

关于理想解决方案的外观有什么想法,不是具体实现的形式,而是从一般设计的角度来看?

我是单元测试的新手,很难将东西彼此分离。

最佳答案

在我看来,您的类 ItemManager 必须调用 DatabaseHelper 来编写项目,但您的单元测试只是想确保它确实如此。您不想测试 DatabaseHelper 是否实际将项目写入数据库,那将是另一个测试。

我会修改您的类的设计:DatabaseHelper.getInstance() 不应直接在方法中完成。您的 ItemManager 应该有一个包含 DatabaseHelper 实例的私有(private)字段。这样您就可以模拟它并验证它是否被调用。

使用 Mockito例如:

public void addItem(Item item) {
items.add(0, item);
this.databaseHelper.writeOneItem(item);
}

@Test
public void my_test() {
// GIVEN
DatabaseHelper databaseHelper = mock(DatbaseHelper.class);
ItemManager manager = new ItemManager(databaseHelper);
Item item = new Item()

// WHEN
manager.addItem(item);

// THEN
verify(databaseHelper).writeOneItem(item); // This verifies that the method writeOneItem of the "mock" is called with the "item" parameter
}

// Another test would check that the item is added to the "items" collection

您的单元测试应该专注于测试一个方法,而不是它使用的类的行为。

在我的示例中,我通过构造函数将 DatabaseHelper 注入(inject)到 ItemManager 中,但您可以使用任何方法:构造函数、setter、依赖注入(inject)框架等。

关于Java 解耦数据库操作代码并使其可测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25135395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com