2017-09-13 4 views
2

J'ai la classe A qui prend un ensemble comme dépendance de guice. L'ensemble est singleton. Ci-dessous l'exemple de code:Google Guice: Mock une méthode @provides consiste en un ensemble d'objet

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); 
     } 
    } 

} 

Voici le module Guice qui injecte la dépendance:

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

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

Je veux railler la méthode storeValue et que je dois se moquer de l'ensemble. Je ne suis pas capable de se moquer de l'ensemble en utilisant guice. Si je me moque comme ci-dessous, il donne l'erreur d'assertion (pas d'interactions avec cette maquette)

@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") 
} 

Répondre

1

Si vous avez besoin d'utiliser Guice dans vos tests unitaires, ce qui est le plus probable va dans la mauvaise direction. L'un des plus grands avantages de l'injection de dépendance est que les tests deviennent faciles, car vous pouvez transmettre des dépendances contrôlées par vous. Je suppose que vous voulez tester la classe A et spécifiquement la méthode storeValue. Pour cela, vous n'avez même pas besoin de se moquer

@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)); 
} 
+0

L'utilisation d'un cadre DI dans vos tests ** unit ** indique que quelque chose va dans la mauvaise direction. Utiliser un framework DI dans vos tests ** d'intégration ** me semble OK – Pelocho

+0

@Pelocho Bon point! Je l'ai changé en tests unitaires –

0

J'ai trouvé ce que l'erreur était, je devrais retourner simulacre lors de la fourniture à mon test unitaire. Cela devrait ressembler à ceci:

@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; 
     } 
    }