Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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 我如何用假测试模块代替Guice模块进行单元测试?_Java_Spring_Unit Testing_Guice - Fatal编程技术网

Java 我如何用假测试模块代替Guice模块进行单元测试?

Java 我如何用假测试模块代替Guice模块进行单元测试?,java,spring,unit-testing,guice,Java,Spring,Unit Testing,Guice,以下是我们在新应用程序中的使用方式: public class ObjectFactory { private static final ObjectFactory instance = new ObjectFactory(); private final Injector injector; private ObjectFactory() throws RuntimeException { this.injector = Guice.createInjector(new

以下是我们在新应用程序中的使用方式:

public class ObjectFactory {
  private static final ObjectFactory instance = new ObjectFactory();
  private final Injector injector;

  private ObjectFactory() throws RuntimeException {
    this.injector = Guice.createInjector(new Module1());
  }

  public static final ObjectFactory getInstance() {
    return instance;
  }

  public TaskExecutor getTaskExecutor() {
    return injector.getInstance(TaskExecutor.class);
  }
}
Module1
定义了需要如何构造
TaskExecutor

在代码中,我们使用
ObjectFactory.getInstance().getTaskExecutor()
来获取
TaskExecutor
的实例

在单元测试中,我们希望能够将其替换为
FakeTaskExecutor
,本质上,我们希望在调用
ObjectFactory.getInstance().getTaskExecutor()
时获得
FakeTaskExecutor
的实例

我正在考虑实现一个
假模块
,该模块将由喷油器使用,而不是
模块1


在春季,我们只需使用
@Autowired
注释,然后为
Test
Production
定义单独的bean,并使用
Spring4JunitRunner
运行我们的测试;我们正在尝试对Guice进行类似的操作。

好的,首先要做的事情是:您似乎没有按照预期的方式使用Guice。一般来说,您希望使用
Guice.createInjector()
启动整个应用程序,并让它为您创建所有构造函数参数,而无需调用
new

典型的用例可能是这样的:

public class Foo {
  private final TaskExecutor executor;

  @Inject
  public Foo(TaskExecutor executor) {
    this.executor = executor;
  }
}
@RunWith(JukitoRunner.class)
public class FooTest {
  public static class Module extends JukitoModule {
    @Override
    protected void configureTest() {
      bindMock(TaskExecutor.class).in(TestSingleton.class);
    }
  }

  @Test
  public void testSomething(Foo foo, TaskExecutor executor) {
     foo.doSomething();
     verify(executor, times(2)).someMethod(eq("Hello World"));
  }
}
这是因为Foo的实例本身被注入到对象图中。见:

通过依赖项注入,对象在其构造函数中接受依赖项。要构造对象,首先要构建其依赖项。但是要构建每个依赖项,您需要它的依赖项,等等。因此,当您构建一个对象时,您确实需要构建一个对象图

手工构建对象图是劳动密集型的,容易出错,并且使测试变得困难。相反,Guice可以为您构建对象图。但首先,需要配置Guice以完全按照您的需要构建图形

因此,通常情况下,您不会创建单例模式并将注入器放入其中,因为您不应该在主类之外调用
Guice.createInstance
;让喷油器为您完成所有工作


话虽如此,要解决您实际询问的问题,您需要使用

JUnit、Guice和Mockito的综合能力。而且这听起来像是一种很酷的武术

让我们回到我上面描述的用例。在朱基托,你可以这样写
FooTest

public class Foo {
  private final TaskExecutor executor;

  @Inject
  public Foo(TaskExecutor executor) {
    this.executor = executor;
  }
}
@RunWith(JukitoRunner.class)
public class FooTest {
  public static class Module extends JukitoModule {
    @Override
    protected void configureTest() {
      bindMock(TaskExecutor.class).in(TestSingleton.class);
    }
  }

  @Test
  public void testSomething(Foo foo, TaskExecutor executor) {
     foo.doSomething();
     verify(executor, times(2)).someMethod(eq("Hello World"));
  }
}
这将验证由via Jukito生成的您的,已经使用字符串
“Hello World”
调用了方法
someMethod
两次


这就是为什么您不希望以您描述的方式使用
ObjectFactory
生成对象;Jukito在其单元测试中为您创建了注入器,因此很难使用模拟注入器,您必须编写大量的样板文件。

好的,首先要做的是:您似乎没有按照预期的方式使用Guice。一般来说,您希望使用
Guice.createInjector()
启动整个应用程序,并让它为您创建所有构造函数参数,而无需调用
new

典型的用例可能是这样的:

public class Foo {
  private final TaskExecutor executor;

  @Inject
  public Foo(TaskExecutor executor) {
    this.executor = executor;
  }
}
@RunWith(JukitoRunner.class)
public class FooTest {
  public static class Module extends JukitoModule {
    @Override
    protected void configureTest() {
      bindMock(TaskExecutor.class).in(TestSingleton.class);
    }
  }

  @Test
  public void testSomething(Foo foo, TaskExecutor executor) {
     foo.doSomething();
     verify(executor, times(2)).someMethod(eq("Hello World"));
  }
}
这是因为Foo的实例本身被注入到对象图中。见:

通过依赖项注入,对象在其构造函数中接受依赖项。要构造对象,首先要构建其依赖项。但是要构建每个依赖项,您需要它的依赖项,等等。因此,当您构建一个对象时,您确实需要构建一个对象图

手工构建对象图是劳动密集型的,容易出错,并且使测试变得困难。相反,Guice可以为您构建对象图。但首先,需要配置Guice以完全按照您的需要构建图形

因此,通常情况下,您不会创建单例模式并将注入器放入其中,因为您不应该在主类之外调用
Guice.createInstance
;让喷油器为您完成所有工作


话虽如此,要解决您实际询问的问题,您需要使用

JUnit、Guice和Mockito的综合能力。而且这听起来像是一种很酷的武术

让我们回到我上面描述的用例。在朱基托,你可以这样写
FooTest

public class Foo {
  private final TaskExecutor executor;

  @Inject
  public Foo(TaskExecutor executor) {
    this.executor = executor;
  }
}
@RunWith(JukitoRunner.class)
public class FooTest {
  public static class Module extends JukitoModule {
    @Override
    protected void configureTest() {
      bindMock(TaskExecutor.class).in(TestSingleton.class);
    }
  }

  @Test
  public void testSomething(Foo foo, TaskExecutor executor) {
     foo.doSomething();
     verify(executor, times(2)).someMethod(eq("Hello World"));
  }
}
这将验证由via Jukito生成的您的,已经使用字符串
“Hello World”
调用了方法
someMethod
两次


这就是为什么您不希望以您描述的方式使用
ObjectFactory
生成对象;Jukito在其单元测试中为您创建了注入器,而注入模拟将非常困难,您必须编写大量的样板文件。

您研究过模拟吗?Mockito是我推荐的API。
FakeTaskExecutor
可以是模拟的,也可以是双重测试,我不知道如何在
ObjectFactory
中拦截注入器。Mockito和PowerMock是实现这一点的唯一方法吗?如果是的话,我们是否错误地使用了Guice。您是否研究过mocking?Mockito是我推荐的API。
FakeTaskExecutor
可以是模拟的,也可以是双重测试,我不知道如何在
ObjectFactory
中拦截注入器。Mockito和PowerMock是否是实现这一点的唯一方法,如果是,我们是否错误地使用了Guice。谢谢,这很有帮助。我们将首先回顾如何使用guice。谢谢,这很有帮助。我们将首先回顾如何使用guice。