第一次使用Spock(对Groovy的了解有限),我怀疑我正在使用Spock的"one giant gotcha":
对同一个方法调用的模拟和存根必须发生在同一个交互中。
但是我不太明白我的例子如何匹配其他问题(例如1,2,3)-所有这些都涉及返回值的方法,其中所讨论的方法在given
代码中被模拟,然后在then
中被验证。我的代码正在验证void
方法。
这是我正在测试的代码:
package com.company
import app.cash.licensee.LicenseeExtension
import app.cash.licensee.LicenseePlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
class ThirdPartyLicensesCheckPlugin implements Plugin<Project> {
@Override
void apply(final Project project) {
project.pluginManager.apply(LicenseePlugin)
def licenseeExtension = project.extensions.findByType(LicenseeExtension)
project.pluginManager.withPlugin("app.cash.licensee") {
licenseeExtension.ignoreDependencies("com.company", "common-utils") {
because "internal project"
}
}
}
}
我想验证许可证插件的应用和配置是否正确。
这是我的测试代码:
package com.company
import app.cash.licensee.LicenseeExtension
import app.cash.licensee.LicenseePlugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.plugins.PluginManager
import spock.lang.Specification
class ThirdPartyLicensesCheckPluginTest extends Specification {
private ThirdPartyLicensesCheckPlugin plugin
// Class dependencies
// Mocks for tests
private Project project
private PluginManager pluginManager
private LicenseeExtension licenseeExtension
def setup() {
plugin = new ThirdPartyLicensesCheckPlugin()
project = Mock(Project)
pluginManager = Mock(PluginManager)
project.pluginManager >> pluginManager
licenseeExtension = Mock(LicenseeExtension)
project.extensions >> Mock(ExtensionContainer) {
findByType(LicenseeExtension) >> licenseeExtension
}
}
def "the cashapp/licensee plugin is applied to the project"() {
given: "a Gradle project"
when: "this plugin is applied"
plugin.apply(project)
then: "the cashapp/licensee plugin is applied"
1 * pluginManager.apply(LicenseePlugin)
1 * pluginManager.withPlugin("app.cash.licensee", _)
1 * licenseeExtension.ignoreDependencies("com.company", "common-utils") { because("internal project")}
}
}
我遇到的失败是:
Too few invocations for:
1 * licenseeExtension.ignoreDependencies("com.company", "common-utils") { because("internal project")} (0 invocations)
Unmatched invocations (ordered by similarity):
None
我尝试在检查withPlugin
的同时验证action参数,如下所示:
package com.company
import app.cash.licensee.LicenseeExtension
import app.cash.licensee.LicenseePlugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.plugins.PluginManager
import spock.lang.Specification
class ThirdPartyLicensesCheckPluginTest extends Specification {
private ThirdPartyLicensesCheckPlugin plugin
// Class dependencies
// Mocks for tests
private Project project
private PluginManager pluginManager
private LicenseeExtension licenseeExtension
def setup() {
plugin = new ThirdPartyLicensesCheckPlugin()
project = Mock(Project)
pluginManager = Mock(PluginManager)
project.pluginManager >> pluginManager
licenseeExtension = Mock(LicenseeExtension)
project.extensions >> Mock(ExtensionContainer) {
findByType(LicenseeExtension) >> licenseeExtension
}
}
def "the cashapp/licensee plugin is applied to the project"() {
given: "a Gradle project"
when: "this plugin is applied"
plugin.apply(project)
then: "the cashapp/licensee plugin is applied"
1 * pluginManager.apply(LicenseePlugin)
1 * pluginManager.withPlugin("app.cash.licensee") {
licenseeExtension.ignoreDependencies("wrong.group", "incorrect-project") { because("the wrong reason")}
}
}
}
但这总是通过,即使验证是错误的。
1条答案
按热度按时间osh3o9ms1#
虽然我同意@tim_yates的观点,您可能希望使用集成测试,但您的问题是您没有调用闭包。
下面是一个简化版本:
Groovy Web Console
你不能Assert闭包是这样传递的,它们不是简单的值。
你需要模仿它,例如像这样:
Groovy Web Console
行
1 * pluginContainer.withPlugin('123', _) >> { reasonMock.with(it[1]) }
将调用闭包,reasonMock
被设置为delegate
。