如何对复杂对象进行单元测试?

For*_*ign 5 java junit unit-testing

假设您想为游戏创建单元测试。

您拥有该类Player,该类具有该类的局部变量World(由构造函数实例化),并且该World对象具有与数据库的打开连接。

因此,player.breakBlock()方法将调用world.breakBlockAt(x,y,z)world.breakBlockAt(int x, int y, int z)方法将对数据库执行更改并返回结果。

在这种情况下,您有复杂的“对象依赖关系”,执行测试的最佳方法是什么?

目前,我基本上正在启动整个游戏环境,使用测试数据库,生成一个假玩家并使用它进行测试。

Cru*_*ool 3

Player要在没有数据库的情况下测试您的类,您可以使用EasyMockMockito等模拟框架来创建对象的模拟World,预先记录您期望Player类调用的方法,然后验证该方法是否实际被调用。

您还可以让模拟对象拦截方法调用并将其替换为自定义逻辑。例如,您可以将调用委托给修改数据库而不是实际数据库的breakBlockAt方法。HashMap然后,返回的值可能会表现不同,具体取决于先前的调用已经对HashMap.

当然,您的类仍然应该有一个单独的测试用例World,以实际测试与数据库一起使用的逻辑(但不会增加类的复杂性Player)。这基本上是一个集成测试,您可以确保 JDBC 语句或 JPA 对象生成有效的 SQL,该 SQL 在与您选择的数据库方言一起使用时可以正常工作。像Testcontainers这样的库可用于在单元测试中的 Docker 容器中设置空数据库。唯一的要求是您的测试环境已运行 Docker 并准备好执行。