单元测试JSR-330注入的对象

时间:2013-11-05 13:03:01

标签: java guice jsr330 hk2

我以前使用过Spring DI,我认为其中一个好处就是我可以在不涉及Spring的情况下测试我的Spring bean类(为简洁起见省略了导入):

public class Foo {
    private String field;

    public void setField(String field) { this.field = field; }
    public String getField() { return field; }
} 

public class TestFoo {
    @Test
    public void test_field_is_set() {
       Foo foo = new Foo();
       foo.setField("Bar");
       assertEquals("Bar", foo.getField());
    }
}

现在我正在尝试使用JSR-330,这意味着没有明确地编写setter。

到目前为止,我正在使用Hk2,纯粹是因为有些关于Jersey与Hk2绑定的轶事,并且难以与其他JSR-330实现共存。

public class Foo {
   @Inject 
   private String field;
}

我有一半期望发生一些魔法,因此@Inject注释导致一个setter变得可用,但事实并非如此:

Foo foo = new Foo();
foo.setField("Bar"); // method setField(String) is undefined for the type Foo
  • 如何在不调用框架的情况下(方便地)测试这种带注释的类?
  • 如果不这样做,我怎么能以便携方式调用框架(即没有将我的测试代码紧密耦合到Hk2,Guice等)。
  • 如果不这样,那么以这种方式测试类的典型,干净的方法是什么?

4 个答案:

答案 0 :(得分:2)

最简单的方法是使字段包为私有(而不是私有),然后在测试中直接设置它们。 (如果测试在同一个包中,那就有效)

public class Foo {
   @Inject 
   String field;
}



Foo foo = new Foo();
foo.field = "bar";

这具有避免反射的优点,因此可以安全地进行重构。

答案 1 :(得分:1)

你提到的现场注入方法实际上是典型的春季风格;许多程序员根本没有为私有注入字段编写setter。 Spring(带有@Autowired@Inject)和JSR-330容器通常使用直接场反射而不是设置器来注入字段。

因此,如果您不想使用任何DI框架,您可以自己将必要的反射代码编写到单元测试中,但这似乎有点过分以避免测试依赖;毕竟,使用@Inject的关键在于您正在编写接口,并且不要避免使用JVM来避免与它耦合。

测试此类类的常用方法是为您喜欢的任何容器设置测试上下文,并在该上下文中运行单元测试。如果您正在使用Spring,那么您需要在applicationContext-test.xml目录(或等效文件)中放置TestConfig文件或src/test/类,如果您使用的是Guice,则需要编写用于连接模拟或测试数据集的模块。

答案 2 :(得分:1)

事实证明,依赖私有/受保护的字段访问的框架并不是那么罕见。 Hibernate,JPA,几个JSR-330实现,包括Spring本身,都是这样做的。

Spring的spring-test包提供了一个ReflectionTestUtils类,其中包含用于访问这些字段的静态方法。

使用这个可以测试问题中的类:

import static org.springframework.test.util.ReflectionTestUtils.*;

...

@Test
public void testUsingSpringReflectionTestUtils() {
    Foo foo = new Foo();
    setField(foo, "field", "Bar");
    assertEquals("Bar", foo.getField());
}

您需要在测试类路径中使用spring-test和spring-core才能使用它,但它不会为您的生产代码添加对Spring的依赖。

(评论欢迎关于相同原则欢迎的替代实现。我认为不值得推出自己的,不管它是多么简单,因为Spring有一个很好的实现。)

答案 3 :(得分:1)

尝试“针”:http://needle.spree.de/overview

needle是一个DI测试框架,它只模拟容器行为,使单元测试变得非常简单。