web-dev-qa-db-fra.com

Utilisation de Mockito pour simuler une méthode de classe dans une autre classe

J'essaie d'écrire des tests unitaires avec Mockito/JUnit pour une fonction comme celle-ci:

class1 {
 method {
  object1 = class2.method // method that I want to fake the return value
  // some code that I still want to run
 }
}

Existe-t-il un moyen dans Mockito de bloquer le résultat de class2.method? J'essaie d'améliorer la couverture du code pour class1, je dois donc appeler ses vraies méthodes de production.

J'ai regardé dans l'API Mockito sa méthode d'espionnage mais cela écraserait toute la méthode et non la partie que je veux.

11
Chang Liu

Je pense que je comprends votre question. Permettez-moi de reformuler, vous avez une fonction que vous essayez de tester et vous voulez vous moquer des résultats d'une fonction appelée dans cette fonction, mais dans une classe différente. J'ai géré cela de la manière suivante.

public MyUnitTest {
    private static final MyClass2 class2 = mock(MyClass2.class);

    @Begin
    public void setupTests() {
        when(class2.get(1000)).thenReturn(new User(1000, "John"));
        when(class2.validateObject(anyObj()).thenReturn(true);
    }

    @Test
    public void testFunctionCall() {
        String out = myClass.functionCall();
        assertThat(out).isEqualTo("Output");
    }
}

Ce que cela fait, c'est que dans la fonction enveloppée de l'annotation @Before, je configure la façon dont je veux que les fonctions de la classe2 répondent en fonction d'entrées spécifiques. Ensuite, à partir du test réel, j'appelle simplement la fonction que j'essaie de tester dans la classe que je veux tester. Dans ce cas, myClass.functionCall () s'exécute normalement et vous n'écrasez aucune de ses méthodes, mais vous vous moquez simplement des sorties qu'il obtient des méthodes (ou méthode) dans MyClass2.

4
John Brumbaugh

Cela a fonctionné pour moi:

public class Class1Test {

  Class1 class1;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    class1 = new Class1();
  }

  @Test
  public void testClass1Method() {

    Class2 class2 = Mockito.mock(Class2.class);
    class1.setClass2(class2);
    Mockito.when(
            class2.class2Method(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn("some response");

    String actualResponse = class1
            .class1Method("12345", "3333", "4444");
    assertEquals("some response", actualResponse);
  }
}
2
krku

J'ai écrit un exemple simple qui a bien fonctionné, j'espère que cela aide:

method1 () de Class1 appelle method2 () de Class2:

    public class Class1 {
        private Class2 class2 = new Class2();
        public int method1() {
            return class2.method2();
        }
    }

Classe2 et méthode2 ():

    public class Class2 {
        public int method2() {
            return 5;
        }
    }

Et le test:

    import org.junit.Rule;
    import org.junit.Test;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.junit.MockitoJUnit;
    import org.mockito.junit.MockitoRule;

    import static org.junit.Assert.assertEquals;
    import static org.mockito.Mockito.when;

    public class TestClass1 {

        @Mock
        Class2 class2;

        @InjectMocks
        Class1 class1;

        @Rule
        public MockitoRule mockitoRule = MockitoJUnit.rule();

        @Test
        public void testMethod1(){
            when(class2.method2()).thenReturn(29);
            assertEquals(29,class1.method1());
        }
    }
0
Mori