有没有办法让 GroovyMock(在 Spock 中)接受 GString 作为 String 参数?
Is there a way to get GroovyMock (in Spock) accepting a GString for a String argument?
遗憾的是,我还找不到有关此主题的任何有用信息。
我有一些 Spock 测试,我需要使用 GroovyMock
而不是 Mock
- 因为它支持模拟动态方法。
其中一个(非动态)方法采用字符串参数。有时 GString 作为参数传递给该方法。这在生产代码以及 Mock
.
中工作正常
然而,在切换到 GroovyMock
之后,我得到一个 java.lang.IllegalArgumentException: argument type mismatch
异常,将我指向以下行(参见下面的示例):
someClass.someMethod("foo ${1 + 1}")
我确实已经检查了在创建 GroovyMock
期间可用的一些选项是否有帮助。到目前为止,我尝试了 verified
选项 - 不幸的是没有帮助。其他的选项在这里似乎都没有机会派上用场,所以我没有尝试使用它们(而且对于其中的大多数,我什至不知道如何使用它们)。
请查看以下小示例以供参考:
import spock.lang.Specification
class SomeClass {
String someMethod(String arg) {
return arg
}
}
class TestClass {
SomeClass someClass
String callMethod() {
someClass.someMethod("foo ${1 + 1}")
}
}
class FooSpec extends Specification {
def 'pass String to groovyMock mocked method taking a String argument'() {
given:
TestClass testClass = new TestClass()
SomeClass someClass = GroovyMock() // does not work
// SomeClass someClass = Mock() // test works if used instead of the previous line
testClass.someClass = someClass
when:
testClass.callMethod()
then:
1 * someClass.someMethod(_)
}
}
抓得好!我可以在 Spock 1.3-groovy-2.5
和 2.0-M3-groovy-3.0
中确认这种行为。我认为从那里创建一个 Spock issue 和 link 回到这个问题是有意义的。
我已经调试了这个问题并在它被“清理”用于测试错误报告之前打印了堆栈跟踪。您可能想将其添加到新一期:
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:104)
at org.spockframework.mock.runtime.GroovyMockMetaClass.doInvokeMethod(GroovyMockMetaClass.java:83)
at org.spockframework.mock.runtime.GroovyMockMetaClass.invokeMethod(GroovyMockMetaClass.java:39)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at de.scrum_master.Whosebug.q63797837.TestClass.callMethod(FooSpec.groovy:15)
at de.scrum_master.Whosebug.q63797837.TestClass$callMethod.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:119)
at de.scrum_master.Whosebug.q63797837.FooSpec.$spock_feature_0_0(FooSpec.groovy:28)
... 34 more
更新: 另一个发现:如果将目标方法签名更改为 String someMethod(GString arg)
,则测试通过 GroovyMock。因此,问题可能与将 someClass.someMethod("foo ${1 + 1}")
中使用的 GString
转换为 String
.
有关
2020-09-16 更新: 几天前,我代表您创建了 Spock issue #1216,因为您忽略了我建议您自己创建。该错误已经修复,我希望它在下一个 2.0 里程碑版本中可用,当然也可以在最终版本中使用。
遗憾的是,我还找不到有关此主题的任何有用信息。
我有一些 Spock 测试,我需要使用 GroovyMock
而不是 Mock
- 因为它支持模拟动态方法。
其中一个(非动态)方法采用字符串参数。有时 GString 作为参数传递给该方法。这在生产代码以及 Mock
.
然而,在切换到 GroovyMock
之后,我得到一个 java.lang.IllegalArgumentException: argument type mismatch
异常,将我指向以下行(参见下面的示例):
someClass.someMethod("foo ${1 + 1}")
我确实已经检查了在创建 GroovyMock
期间可用的一些选项是否有帮助。到目前为止,我尝试了 verified
选项 - 不幸的是没有帮助。其他的选项在这里似乎都没有机会派上用场,所以我没有尝试使用它们(而且对于其中的大多数,我什至不知道如何使用它们)。
请查看以下小示例以供参考:
import spock.lang.Specification
class SomeClass {
String someMethod(String arg) {
return arg
}
}
class TestClass {
SomeClass someClass
String callMethod() {
someClass.someMethod("foo ${1 + 1}")
}
}
class FooSpec extends Specification {
def 'pass String to groovyMock mocked method taking a String argument'() {
given:
TestClass testClass = new TestClass()
SomeClass someClass = GroovyMock() // does not work
// SomeClass someClass = Mock() // test works if used instead of the previous line
testClass.someClass = someClass
when:
testClass.callMethod()
then:
1 * someClass.someMethod(_)
}
}
抓得好!我可以在 Spock 1.3-groovy-2.5
和 2.0-M3-groovy-3.0
中确认这种行为。我认为从那里创建一个 Spock issue 和 link 回到这个问题是有意义的。
我已经调试了这个问题并在它被“清理”用于测试错误报告之前打印了堆栈跟踪。您可能想将其添加到新一期:
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:104)
at org.spockframework.mock.runtime.GroovyMockMetaClass.doInvokeMethod(GroovyMockMetaClass.java:83)
at org.spockframework.mock.runtime.GroovyMockMetaClass.invokeMethod(GroovyMockMetaClass.java:39)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at de.scrum_master.Whosebug.q63797837.TestClass.callMethod(FooSpec.groovy:15)
at de.scrum_master.Whosebug.q63797837.TestClass$callMethod.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:119)
at de.scrum_master.Whosebug.q63797837.FooSpec.$spock_feature_0_0(FooSpec.groovy:28)
... 34 more
更新: 另一个发现:如果将目标方法签名更改为 String someMethod(GString arg)
,则测试通过 GroovyMock。因此,问题可能与将 someClass.someMethod("foo ${1 + 1}")
中使用的 GString
转换为 String
.
2020-09-16 更新: 几天前,我代表您创建了 Spock issue #1216,因为您忽略了我建议您自己创建。该错误已经修复,我希望它在下一个 2.0 里程碑版本中可用,当然也可以在最终版本中使用。