【问题标题】:How to Mock an Annotated Class?如何模拟带注释的类?
【发布时间】:2019-03-30 20:54:23
【问题描述】:

如何在 Spock 中模拟(或监视)带注释的类,以便断言依赖于注释的逻辑?

Groovy(也可能是 Java)中的一个人为示例显示了一种检查对象集合中特定注释值的方法。想象一下在通过注解过滤后执行的更复杂的逻辑,我想通过模拟集合中的对象来断言。

@FooAnnotation('FOOBAR')
class MainGroovy {
    def findFOOBARs(Object... candidates) {
        candidates.findAll{ it.class.getAnnotation(FooAnnotation)?.value() == 'FOOBAR' }
        //Do something with the filtered objects.
    }
}

传递 Spy 会使注释过滤器失败,因此无法断言任何后续逻辑。

@Unroll
def test() {
    given:
        def foobars = mg.findFOOBARs(mg, new Object(), 'STRING')
    expect:
        foobars.size() == 1
    where:
        mg << [new MainGroovy(), Spy(MainGroovy)]
}

【问题讨论】:

    标签: java groovy annotations mocking spock


    【解决方案1】:

    我可能不知道什么,但我已经对这个用例进行了快速研究。看起来使用 Spock 的 MockSpy 保留来自模拟/间谍类的注释是不可能的。如果我们研究使用 byte-buddy 时类的 Spock creates mocks/spies 是如何使用的,我们会发现它是原始类型的子类。如果我们深入研究默认情况下 byte-buddy 是如何工作的,那么我们会发现它不会保留原始类型的注释,除非另有配置。默认情况下,它只使用带有subclass method ignoring annotations' retention 的 InstrumentedType 的默认工厂。

    我还没有在 Spock 的 GitHub 上发现任何与注释保留相关的问题。 Spock 方面的修复可能看起来很简单,但我不确定这一点。最好在他们的 GitHub 上提问。

    对于简单的情况,作为一个非常丑陋的解决方法,您可以尝试在 Spock 规范中使用 Mockito spy/mock

    【讨论】:

    • 这导致我提出了一个相关问题:Retain annotations on CGLIB proxies?@Inherited 添加到我的自定义@FooAnnotation 使测试通过。
    • 是的,但请注意,这仅适用于类类型的注释,而不适用于接口类型(您也可以模拟)或方法注释等。这也记录在 for JDK。
    • @kriegaex,你能链接到 JDK 文档的相关部分吗?
    • 当然。抱歉,我认为只检查Javadoc for the @Inherited annotation 会很容易且合乎逻辑。
    猜你喜欢
    • 2018-09-13
    • 2021-12-27
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2018-06-25
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多