Mockowanie klas innych niż klasa testowana

0

Witam serdecznie,
dopiero zaczynam poznawać świat testowania i uczę się testów jednostkowych. Napotkałem problem, którego nie mogę obejść. Proszę o wskazówki.
Piszę w Java i używam Junit i potrafię już mockować metody klasy testowanej, ale jak zmockować metodę z innej klasy? Chodzi mi o metodę h() z klasa2 z poniższego przykładu:

    import static org.junit.Assert.*;
     
    import static org.mockito.Mockito.*;
    import static org.powermock.api.support.membermodification.MemberMatcher.method;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.mockito.Mockito;
    import org.mockito.invocation.InvocationOnMock;
    import org.mockito.stubbing.Answer;
    import org.powermock.api.mockito.PowerMockito;
    import org.junit.runner.RunWith;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
     
     
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({klasa.class,klasa2.class})
     
    public class klasaTest {
         klasa kl;
         klasa2 kl2;
     
         @Before
         public void setUp() throws Exception {
               kl2 = new klasa2();
               kl = new klasa(kl2);
         }
     
         @After
         public void tearDown() throws Exception {
              kl2 = null;
              kl = null;
         }
     
         @Test
         public void testF() throws Exception {
     
              klasa mySpy = PowerMockito.spy(kl);
     
              klasa2 mockkl2 = PowerMockito.mock(klasa2.class);
     
              PowerMockito.doAnswer(new Answer<Void>() {
                   public Void answer(InvocationOnMock invocation) {
                        Object[] args = invocation.getArguments();
                        System.out
                             .println("called with argument: " + (Integer) args[0]);
     
                        return null;
                  }
         }).when(mySpy, method(klasa.class, "g")).withArguments(anyInt());
     
    //Mockito.doCallRealMethod().when(mySpy).f();
     
         doNothing().when(mockkl2).h();
     
         mySpy.f();
     
         verify(mySpy);
     
         }
     
    }
     
     //klasa testowana
    class klasa {
     
         klasa2 kl2;
     
         public klasa(klasa2 kl2)
         {
              this.kl2 = kl2;
         }
     
         public void f()
         {
              System.out.println("metoda f");
              g(3);
              g(4);
              kl2.h();
              kl2.h();
         }
       
         private void g(int a)
         {
              System.out.println("tego nie chcemy");
         }
    }
     
    class klasa2 {
          public void h()
         {
              System.out.println("klasa2 - error");
         }
    } 
1

@wiciu Wtf?
@autor nie rozumiem pytania. musisz zamiast obiektu tej klasy z metoda h() podstawić mocka i tyle. Cały ten kod który podałeś to koszmar.

Jedyny obiekt który powinieneś tworzyć przez new to ten który testujesz. Jego wszystkie zależności i klasy / obiekty z których korzysta to mają być mocki.
Co więcej czasem i testowany obiekt trzeba mockować - power mock potrafi zrobić mocka całego obiektu z wyłączeniem wybranych metod (przydatne jak testujesz metodę która woła dużo metod z tej samej klasy a ty chcesz testować tylko ta jedną)

0

@Shalom dzięki, właśnie już po napisaniu posta wpadłem dokładnie na to samo. A tak z ciekawości... czemu cały kod to koszmar? :p

0

PowerMockito służy jedynie do mockowania przestarzałego kodu, którego nie możesz zmieniać.
W innych przypadkach powinno się stosować zwykłe Mockito.
Testować powinno się jedynie metody publiczne i nie weryfikować prywatnych zmiennych. Wpp. kod testu jest zbyt związany z kodem testowanym i każda zmiana w klasie testowanej wymaga zmiany w teście. Zwiększa to koszt utrzymania aplikacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1