Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单元测试JSR-330注入对象_Java_Guice_Jsr330_Hk2 - Fatal编程技术网

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

Java 单元测试JSR-330注入对象,java,guice,jsr330,hk2,Java,Guice,Jsr330,Hk2,我以前使用过SpringDI,我认为其中一个好处是我可以在不涉及Spring的情况下测试我的Springbean类(为简洁起见,省略了导入): 现在我正在试验JSR-330,这意味着不显式地编写setter 到目前为止,我一直在使用Hk2,纯粹是因为一些关于Jersey与Hk2绑定的趣闻轶事,使得它难以与其他JSR-330实现共同习惯 public class Foo { @Inject private String field; } 我有点期待会发生一些神奇的事情,@Injec

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

现在我正在试验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等紧密耦合)
  • 如果做不到这一点,测试以这种方式注释的类的典型、干净的方法是什么

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

因此,如果您不想使用任何DI框架,您可以自己在单元测试中编写必要的反射代码,但为了避免测试依赖性,这似乎有些过分;毕竟,使用
@Inject
的意义在于,您正在对一个接口进行编码,并且您不能避免使用JVM来避免与它的耦合


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

事实证明,依赖私有/受保护字段访问的框架并不少见。Hibernate、JPA和几个JSR-330实现,包括Spring本身,都能做到这一点

Spring的Spring测试包提供了一个包含用于访问这些字段的静态方法的类

使用此选项可以测试问题中的类,因此:

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

...

@Test
public void testUsingSpringReflectionTestUtils() {
    Foo foo = new Foo();
    setField(foo, "field", "Bar");
    assertEquals("Bar", foo.getField());
}
您需要在测试类路径中使用SpringTest和SpringCore,这样才能工作,但它不会为您的生产代码添加对spring的依赖

(欢迎对同一原则的替代实现发表评论欢迎。我认为,考虑到Spring有一个很好的实现,不管它多么简单,都不值得自己动手。)

尝试一下“针”:


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

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


这样做的好处是避免了反射,因此可以安全地进行重构。

可能的重复我认为这是有区别的。链接的问题是“我是否应该写二传”。这个问题是“如果我不使用setter,我应该如何测试”。只需使用构造函数注入。这个问题到时候就会解决了。
import static org.springframework.test.util.ReflectionTestUtils.*;

...

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



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