ken*_*who 3 grails groovy unit-testing spock
我在下面有一个非常简单的方法。它调用另一种方法来软删除 API 密钥,然后调用另一种方法来创建一个新的并返回它。
测试也在下面,它只是检查这两个方法是否被正确调用。但是仍然在两种方法上都得到 0 调用错误。是什么导致了这个问题?
AuthApiKeyPair updateApiKeyPair(AuthApiKeyPair apiKeyPair, Boolean createNewKey) {
AuthApiKeyPair newKeyPair
if (createNewKey) {
deleteApiKeyPair(apiKeyPair)
//The key will be created with the same info as the previous key.
newKeyPair = createApiKeyPair(apiKeyPair.label, apiKeyPair.accountMode, apiKeyPair.source)
}
newKeyPair
}
Run Code Online (Sandbox Code Playgroud)
测试:
def "should soft delete key pair and create new one"() {
setup:
AuthApiKeyPair apiKeyPair = AuthApiKeyPair.build(acquirerId: 123, source: PaymentSource.BOARDING_API, label: 'Boarding API key')
when:
service.updateApiKeyPair(apiKeyPair, true)
then:
1 * service.deleteApiKeyPair(apiKeyPair)
1 * service.createApiKeyPair(apiKeyPair.label, apiKeyPair.accountMode, apiKeyPair.source)
}
Run Code Online (Sandbox Code Playgroud)
如果您考虑一下您的测试,您会发现在最好的情况下,它测试的是 Spock 的模拟机制,而不是您的业务代码。您还没有向我们展示您的测试规范的完整课程,但是根据您的场景,我们可以假设service您的测试只是一个模拟。如果这是真的,那么你不能指望这两个调用:
then:
1 * service.deleteApiKeyPair(apiKeyPair)
1 * service.createApiKeyPair(apiKeyPair.label, apiKeyPair.accountMode, apiKeyPair.source)
Run Code Online (Sandbox Code Playgroud)
即将发生。仅仅是因为模拟类不执行真正的方法。
我强烈建议您测试一个真正的类,而不是测试特定方法导致的调用类型,而是调用特定方法的预期(和确定性)结果是什么。您可以service.updateApiKeyPair(apiKeyPair, true)对 inwhen子句中的真实对象执行,然后您可以检查是否创建了新的 API 密钥对(并保存在您使用的存储中),以及旧对是否不再存在。与仅检查调用相比,此类测试至少有一些好处:
service.updateApiKeyPair()只要它产生相同的结果,您的测试仍然有用(因为该测试不会像调用测试那样限制您的实现),当然,它可能需要一些设计更改。我猜你的服务类使用了一些注入的 DAO 或存储 API 密钥对的存储库。考虑为您的测试提供此类 DAO 的内存中实现 - 一个类,而不是在真实数据库中持久化对象,将所有对象存储在内部ConcurrentMap<K,V>. 多亏了这一点,您仍然可以将测试作为单元测试运行,并且您可以测试使用createNewKey参数设置更新 API 密钥对true是否完全符合您的预期。或者,您可以使用 H2 数据库替换编写集成测试,但这只会使您的测试引导程序更长。这是你的选择。
有一条规则值得记住——如果您的类/组件/功能等难以进行单元测试,则意味着做出了错误的设计选择。
Spy对象最后我特意提到了一件事。Spock 支持所谓的“间谍”对象,其行为类似于真实对象,但它们允许您存根某些部分并将此对象视为模拟对象,例如调用计数。但即使是 Spock 的作者也警告开发人员不要使用此功能:
(使用此功能前请三思。根据规范更改代码的设计可能会更好。)
来源:http : //spockframework.org/spock/docs/1.0/interaction_based_testing.html#spies
我不知道 Grails 是否有用于创建 Spy 而不是 Mock 的测试的注释,但是您始终可以按照官方文档创建简单的 Spock 单元测试,将您的服务实例化为 Spy,然后您可以尝试计算调用次数。不过,我不建议这样做,只是为了记录而提及这一点。
| 归档时间: |
|
| 查看次数: |
1746 次 |
| 最近记录: |