web-dev-qa-db-fra.com

Mockito: méthode d'instance simulée pour toutes les instances d'une classe

J'essaie de remplacer une méthode d'instance d'une classe particulière afin que, lorsqu'une instance de cette classe Foo appelle cette méthode d'instance doSomething, la même object soit renvoyée (voir le code ci-dessous). Cependant, mockito n'autorise aucun match en dehors de la vérification ou du stubbing.

Bar object = new Bar();
given(any(Foo.class).doSomething(Arg.class)).willReturn(object);

Et en Foo.class:

Bar doSomething(Arg param) {
    Bar bar = new Bar();
    // Do something with bar
    return bar;
}

Est-ce que je peux atteindre cet objectif avec Mockito? Merci!

8
ddolce

Cela devrait fonctionner:

 public class FooTest {
     @Mock
     private Foo foo;

     ...
     @Before
     public void setUp() {
        MockitoAnnotations.initMocks(this);
     }

     @Test
     public void testSomething() {
        Bar object = new Bar();
        when(foo.doSomething(any(Any.class))).thenReturn(object);
        ...
     }
}

Mise à jour 1  

Vous devez utiliser PowerMock si vous souhaitez que Foo renvoie la même instance de Bar lorsque vous appelez la méthode doSomething sur une instance de Foo. Voici un exemple:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Foo.class)
public class FooMockAllInstanceTest {

    @Test
    public void testMockInstanceofObjectCreation() throws Exception {
        Bar mockBar = PowerMockito.mock(Bar.class);
        when(mockBar.sayHello()).thenReturn("Hi John!");
        PowerMockito.whenNew(Bar.class)
                .withNoArguments()
                .thenReturn(mockBar);

        Foo myFooOne = new Foo();
        assertEquals(mockBar,  myFooOne.doSomething("Jane"));

        Foo myFooTwo = new Foo();
        assertEquals(mockBar,  myFooTwo.doSomething("Sarah"));

        Baz bazOne = new Baz();
        assertEquals(mockBar, bazOne.doSomething("Sam"));

        Baz bazTwo = new Baz();
        assertEquals(mockBar, bazTwo.doSomething("Nina"));
    }
}

Cet exemple renvoie le même objet Bar même lorsque Baz est appelé. Voici la classe Baz,

public class Baz {

    public Bar doSomething(String name) {
        Foo foo = new Foo();
        return foo.doSomething(name);
    }
}

Mise à jour 2

Il existe un autre moyen légèrement meilleur de tester avec PowerMock. Et voilà,

@Test
public void testStubbingMethod() throws Exception {
    Bar mockBar = PowerMockito.mock(Bar.class);
    when(mockBar.sayHello()).thenReturn("Hi John!");

    PowerMockito.stub(PowerMockito.method(Foo.class, "doSomething",
            String.class)).toReturn(mockBar);

    Foo myFooOne = new Foo();
    assertEquals(mockBar, myFooOne.doSomething("Jane"));

    Foo myFooTwo = new Foo();
    assertEquals(mockBar, myFooTwo.doSomething("Sarah"));

    Baz bazOne = new Baz();
    assertEquals(mockBar, bazOne.doSomething("Sam"));

    Baz bazTwo = new Baz();
    assertEquals(mockBar, bazTwo.doSomething("Nina"));
}
2
Indra Basak