首页 > 解决方案 > 如何对复杂对象进行单元测试?

问题描述

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

你有一个Player类,它有一个类的局部变量World(由构造函数实例化),并且该World对象与数据库有一个开放的连接。

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

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

目前我基本上是在启动整个游戏环境,使用一个测试数据库,生成一个假 Player 并将其用于测试。

标签: javaunit-testingjunit

解决方案


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

您还可以让您的模拟对象拦截方法调用并将其替换为自定义逻辑。例如,您可以将调用委托给breakBlockAt修改 aHashMap而不是实际数据库的方法。并且返回的值可能会根据之前的调用已经对HashMap.

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


推荐阅读