【发布时间】:2017-11-29 07:30:29
【问题描述】:
作为一个在单元测试和模拟方面没有经验的人,我学习了关于 JUnit 和 Mockito 的初学者教程并进行了一些练习。
现在,我需要对一些在 MySQL 数据库上执行基本数据库操作的类方法进行单元测试。我不想对数据库进行真正的更改。
在我的代码中:
@InjectMocks private DBConnection dbConnection;
@Mock private DBConnection mockDBConnection;
@Test
public void testDropTable() {
Mockito.when(mockDBConnection.dropTable()).thenReturn(0);
// dropTable() returns 0 if table dropped
int result = dbConnection.dropTable();
Assert.assertEquals(result, 0);
}
为了验证(使用 assertEquals() )测试结果,我调用了真正的 dropTable() 方法,它确实丢弃了表(实际上很明显,因为我正在调用真正的 DBConnection 实例)
有没有办法在不访问真实数据库的情况下验证这样的方法?还是我误解了单元测试和模拟的概念?
【问题讨论】:
-
代码看起来很奇怪。为什么你有两个
DBConnection对象?您正在“真实”实例上调用 dropTable() 。dbConnection是否以某种方式包含它委托的另一个DBConnection字段?如果没有,您的代码将毫无意义,因为您创建了一个模拟 DBConnection 和一个真实的。如果DBConnection中有一个DBConnection字段,这将不起作用。也许提供一些DBConnection代码是个好主意。 -
是的,我有 2 个实例。一个是真实对象,另一个是模拟对象。 DBConnection 类中没有成员类。 DBConnection 类只有 dropTable()、addEntry() 等方法,并且有私有字段,这些字段是提供给 DriverManager 的主机、数据库和端口信息(基本 JDBC 连接)
-
好的,这真的很解释,感谢您的评论。我也期待这样的结果。但是,我如何在不接触数据库的情况下测试它呢?有什么办法吗?唯一的解决方案是创建与开发数据库具有相同配置的测试数据库吗?从您的评论中我了解到,我需要驾驶真正的汽车才能确保它能够正常工作?
-
一旦您的代码与另一个系统交互,如果没有其他系统就无法可靠地测试它。这可以是数据库的副本或内存版本,但其他所有内容都是不完整的。也许有间接的测试方法,但这些方法需要创建高度复杂的测试,实际上可能只是模拟外部系统的很大一部分。对于这些东西,存在集成测试来测试您的系统与其他系统的集成程度。
标签: unit-testing junit mocking mockito tdd