如何模拟带注释的 Class?

How to Mock an Annotated Class?

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

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)]
}

我可能没有意识到某些事情,但我已经对这个用例进行了快速研究。看起来不可能使用 Spock 的 MockSpy 保留来自 mocked/spied 类 的注释。如果我们研究一下 Spock creates mocks/spies of a class when byte-buddy is used, we'll see that it subclasses the original type. If we look deeper into how byte-buddy works by default, then we will see that it doesn't retain annotations of the original type unless configured otherwise. By default, it just uses InstrumentedType's Default Factory with subclass method ignoring annotations' retention.

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

上询问

作为简单案例的一种非常丑陋的解决方法,您可以在 Spock 规范

中尝试 Mockito spy/mock