【问题标题】:Is there a way to get GroovyMock (in Spock) accepting a GString for a String argument?有没有办法让 GroovyMock(在 Spock 中)接受 GString 作为 String 参数?
【发布时间】:2020-09-08 16:17:16
【问题描述】:

很遗憾,我还没有找到有关此主题的任何有用信息。

我有一些 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(_)
    }
}

【问题讨论】:

    标签: groovy mocking spock


    【解决方案1】:

    好收获!我可以在 Spock 1.3-groovy-2.52.0-M3-groovy-3.0 中确认这种行为。我认为创建一个Spock issue 并从那里链接回这个问题是有意义的。

    我已经调试了这个问题并在它被“清理”之前打印了堆栈跟踪以进行测试错误报告。您可能希望将其添加到新问题中:

    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.stackoverflow.q63797837.TestClass.callMethod(FooSpec.groovy:15)
        at de.scrum_master.stackoverflow.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.stackoverflow.q63797837.FooSpec.$spock_feature_0_0(FooSpec.groovy:28)
        ... 34 more
    

    更新: 另一个发现:如果您将目标方法签名更改为 String someMethod(GString arg),则使用 GroovyMock 的测试通过。因此,问题可能与将someClass.someMethod("foo ${1 + 1}") 中使用的GString 转换为String 有关。


    2020 年 9 月 16 日更新: 几天前,我代表您创建了 Spock issue #1216,因为您忽略了我自己创建的建议。该错误已经修复,我希望它可以在下一个 2.0 里程碑版本中使用,当然也可以在最终版本中使用。

    【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2020-12-26
    相关资源
    最近更新 更多