Groovy/Spock测试具有成员@Inject的Java类

Groovy/Spock测试具有成员@Inject的Java类,java,unit-testing,groovy,spock,Java,Unit Testing,Groovy,Spock,我试图测试一个Java类,该类使用@Inject注入了一个成员 我想测试一下这个方法 public class SomeJavaClass { @Inject private SomeFactory someFactory; private SomeDAO someMethod(Map someMap) { SomeDAO someDAO = someFactory.create(); //some code } } 我的类没

我试图测试一个Java类,该类使用@Inject注入了一个成员

我想测试一下这个方法

public class SomeJavaClass {

    @Inject
    private SomeFactory someFactory;

    private SomeDAO someMethod(Map someMap) {
        SomeDAO someDAO = someFactory.create();
        //some code
    }
}

我的类没有显式构造函数

如果您的字段是私有的,并且您不使用构造函数,那么如何注入它?我认为这是一个错误,因为如果您从外部注入一些东西,您需要为它提供一个接口

下面是一个spock规范,它可以满足您的要求,但将someFactory公开为受保护的成员:

import spock.lang.Specification
import spock.lang.Subject

import javax.inject.Inject

interface SomeFactory {
    SomeDAO create()
}

class SomeDAO {

}

class SomeJavaClass {

    @Inject
    protected SomeFactory someFactory;

    protected SomeDAO someMethod(Map someMap) {
        SomeDAO someDAO = someFactory.create();
        //some code
    }
}

class SomeJavaClassSpec extends Specification {

    def someFactory = Mock(SomeFactory)
    @Subject
    SomeJavaClass subject = new SomeJavaClass(
            someFactory: someFactory
    )

    def "It uses a factory to create some object"() {
        when:
        subject.someMethod([:])

        then:
        1 * someFactory.create() >> new SomeDAO()
    }
}
您还可以使用spock collaborators扩展注释自动注入协作者模拟:


当然,您可以注入到私有字段中(Guice和Spring可以这样做)。您可以使用我的扩展,但如果您添加了构造函数会更好,因为它遵循OOP实践。

您必须在工厂中模拟方法。此外,反射也是可能的,如果是Groovy类,则使用@operator会更容易。只是为了这个答案的未来读者。你是对的,“@”操作符也是如此:)但也许我们不要传播这样可怕的黑客:如果它在官方API中,那么它就不是黑客:D