【问题标题】:Groovy / Spock test a Java class that has a member @InjectGroovy / Spock 测试具有成员 @Inject 的 Java 类
【发布时间】:2015-06-01 15:54:47
【问题描述】:

我正在尝试测试一个使用 @Inject 注入成员的 Java 类。

我想测试 someMethod

public class SomeJavaClass {

    @Inject
    private SomeFactory someFactory;

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

我的类没有显式构造函数

【问题讨论】:

  • 你必须在你的工厂模拟方法。

标签: java unit-testing groovy spock


【解决方案1】:

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

所以这是一个 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 扩展注解自动注入您的合作者 Mocks:

https://github.com/marcingrzejszczak/spock-subjects-collaborators-extension

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 另外,反射是可能的,如果这是 Groovy 类,使用 .@ 运算符会更容易。仅供此答案的未来读者阅读。
    • 你说得对,".@" 运算符确实如此 :) 但也许我们不要传播如此可怕的黑客攻击 :D
    • 如果它在官方 API 中,那么它不是黑客 :D
    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    相关资源
    最近更新 更多