Google Guice:模拟@provides方法由一组对象组成

时间:2017-09-13 15:17:54

标签: java unit-testing mockito guice

我有A类,它将一组视为guice依赖。这套是单身人士。下面是代码示例:

class A
{
   private Set<InetAddress> set;
   private String pingUriPath;
   @Inject
   public A(Set<InetAddress> set, @Named("pingUri") String pingUriPath)
        {
          this.set = set;
          this.pingUriPath = pingUriPath; // this is used somewhere
        }

   public void storeValue(String str)
   {
      if(str.equals("abc"))
       {
          set.add(str);
       }
   }

}

这是注入依赖关系的guice模块:

private class GuiceModule extends AbstractModule {
        @Override
        public void configure() {
          bindConstant().annotatedWith(Names.named("pingUri")).to("/ping");
        }

        @Provides
        @Singleton
        Set<InetAddress> healthyTargets(){
            return Sets.newConcurrentHashSet();
        }
    }

我想模拟方法storeValue,为此我必须模拟该集合。我无法使用guice来模拟该集。 如果我像下面那样嘲笑,它会给出断言错误(没有与这个模拟的交互)

@Mock
Set<InetAddress> mockHealthyTargets;

private class MockClassesModule extends AbstractModule {
        @Override
        public void configure() {
            bindConstant().annotatedWith(Names.named("pingUri")).to("/ping");
        }

        @Provides
        @Singleton
        Set<InetAddress> healthyTargets(){
            return Sets.newConcurrentHashSet();
        }
    }

public test_storeValue()
{
   Injector injector = Guice.createInjector(new MockClassesModule());
   A a = injector.getInstance(A.class);
   a.storeValue("abc");
   verify(mockHealthyTargets).add("abc")
}

2 个答案:

答案 0 :(得分:1)

如果你需要在单元测试中使用guice,那么很可能会出现错误的方向。依赖注入的最大好处之一是测试变得容易,因为您可以传递由您控制的依赖项。

我假设您要测试A类,特别是方法storeValue。为此,你甚至不需要嘲笑

@Test
public void test() {
    // prepare dependencies
    Set<InetAddress> set = Sets.newConcurrentHashSet(); 
    String pingUri = "example.com";

    // prepare input
    String input = "someValue";

    // prepare class under test
    A classUnderTest = new A(set, pingUri);

    // call class under test
    classUnderTest.storeValue(input);

    // check that what you expected happened
    // in this case you expect that the dependency set now contains the input
    assertThat(set, contains(input));
}

答案 1 :(得分:0)

我发现错误是什么,我应该在提供单元测试时返回模拟。它应该是这样的:

@Mock
Set<InetAddress> mockHealthyTargets;

private class MockClassesModule extends AbstractModule {
        @Override
        public void configure() {
            bindConstant().annotatedWith(Names.named("pingUri")).to("/ping");
        }

        @Provides
        @Singleton
        Set<InetAddress> healthyTargets(){
            return mockHealthyTargets;
        }
    }