asc*_*sco 4 java unit-testing design-patterns
我想为以下方法编写测试:
public void addItem(Item item) {
items.add(0, item);
DatabaseHelper.getInstance().writeOneItem(item);
}
Run Code Online (Sandbox Code Playgroud)
该类称为ItemManager,它的职责是管理用户可以保存到列表或从列表中删除的项目.它应与保留列表中项目的Sqlite数据库保持同步.
当DatabaseHelper
(ormlite)没有被引入时init(Context context)
(通常在我的Andoid应用程序启动时发生,但在我的测试中没有完成),它的getInstance()
方法将返回null
并且从上面执行的方法将崩溃.
我该怎么办?我可以init(Context context)
从我的测试中调用,或者DatabaseManager.getInstance()
在调用它之前检查是否为null.但这似乎更像是一种解决方法.在我看来,我不应该在这个方法中做任何数据库的东西,并尝试尽可能地从数据库中分离ItemManager.
关于理想解决方案的外观的任何想法,不是从具体实施的形式,而是从一般的设计角度来看?
我是单元测试的新手,很难将相互之间的东西分开.
在我看来,你的班级ItemManager
必须打电话DatabaseHelper
来写项目,但你的单元测试只是想确保它.您不想测试DatabaseHelper
实际在数据库中写入项目,这将是另一个测试.
我会修改你的类的设计:DatabaseHelper.getInstance()
不应该直接在方法中完成.你ItemManager
应该有一个私有字段与实例DatabaseHelper
.这样你就可以模拟它并验证它是否被调用.
以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
Run Code Online (Sandbox Code Playgroud)
您的单元测试应该专注于测试ONE方法而不是它使用的类的行为.
在我的例子,我注入DatabaseHelper
在ItemManager
通过构造函数,但你可以使用任何方法:构造函数,setter方法,依赖注入框架等.
归档时间: |
|
查看次数: |
306 次 |
最近记录: |