Mam klasę jak poniżej:
public class A {
public A(String test) {
bla bla bla
}
public String check() {
bla bla bla
}
}
Logika w konstruktorze A(String test)
i check()
rzeczy, które próbuję kpić. Chcę wywołania typu: new A($$$any string$$$).check()
zwraca fikcyjny ciąg "test"
.
Próbowałem:
A a = mock(A.class);
when(a.check()).thenReturn("test");
String test = a.check(); // to this point, everything works. test shows as "tests"
whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk);
// also tried:
//whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk);
new A("random string").check(); // this doesn't work
Ale to nie wydaje się działać. new A($$$any string$$$).check()
nadal przechodzi przez logikę konstruktora zamiast pobierać mockowany obiekt A
.
Odpowiedzi:
Kod, który opublikowałeś, działa dla mnie z najnowszą wersją Mockito i Powermockito. Może nie przygotowałeś A? Spróbuj tego:
A.java
public class A { private final String test; public A(String test) { this.test = test; } public String check() { return "checked " + this.test; } }
MockA.java
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(A.class) public class MockA { @Test public void test_not_mocked() throws Throwable { assertThat(new A("random string").check(), equalTo("checked random string")); } @Test public void test_mocked() throws Throwable { A a = mock(A.class); when(a.check()).thenReturn("test"); PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a); assertThat(new A("random string").check(), equalTo("test")); } }
Oba testy powinny przejść z mockito 1.9.0, powermockito 1.4.12 i junit 4.8.2
źródło
PrepareForTest
O ile wiem, nie można kpić z konstruktorów za pomocą mockito, tylko metody. Ale zgodnie z wiki na stronie kodowej Google Mockito istnieje sposób na oszukanie zachowania konstruktora poprzez utworzenie metody w Twojej klasie, która zwraca nową instancję tej klasy. wtedy możesz kpić z tej metody. Poniżej znajduje się fragment bezpośrednio z wiki Mockito :
Jeśli chcesz tylko zwrócić wyszydzony przedmiot ze swojej klasy, myślę, że to powinno działać dla Ciebie. W każdym razie możesz przeczytać więcej o mockowaniu tworzenia obiektów tutaj:
http://code.google.com/p/mockito/wiki/MockingObjectCreation
źródło
Bez korzystania z Powermock .... Zobacz poniższy przykład oparty na odpowiedzi Bena Glassera, ponieważ zajęło mi to trochę czasu ... mam nadzieję, że zaoszczędzi to trochę czasu ...
Oryginalna klasa:
public class AClazz { public void updateObject(CClazz cClazzObj) { log.debug("Bundler set."); cClazzObj.setBundler(new BClazz(cClazzObj, 10)); } }
Zmodyfikowana klasa:
@Slf4j public class AClazz { public void updateObject(CClazz cClazzObj) { log.debug("Bundler set."); cClazzObj.setBundler(getBObject(cClazzObj, 10)); } protected BClazz getBObject(CClazz cClazzObj, int i) { return new BClazz(cClazzObj, 10); } }
Klasa testowa
public class AClazzTest { @InjectMocks @Spy private AClazz aClazzObj; @Mock private CClazz cClazzObj; @Mock private BClazz bClassObj; @Before public void setUp() throws Exception { Mockito.doReturn(bClassObj) .when(aClazzObj) .getBObject(Mockito.eq(cClazzObj), Mockito.anyInt()); } @Test public void testConfigStrategy() { aClazzObj.updateObject(cClazzObj); Mockito.verify(cClazzObj, Mockito.times(1)).setBundler(bClassObj); } }
źródło
Z mockito możesz użyć withSettings (), na przykład jeśli CounterService wymagał 2 zależności, możesz przekazać je jako makietę:
UserService userService = Mockito.mock(UserService.class); SearchService searchService = Mockito.mock(SearchService.class); CounterService counterService = Mockito.mock(CounterService.class, withSettings().useConstructor(userService, searchService));
źródło
Mockito ma ograniczenia testowania metod ostatecznych, statycznych i prywatnych.
dzięki bibliotece testowej jMockit możesz zrobić kilka rzeczy bardzo łatwych i prostych, jak poniżej:
Mock konstruktor klasy java.io.File:
new MockUp<File>(){ @Mock public void $init(String pathname){ System.out.println(pathname); // or do whatever you want } };
Mock metodę statyczną:
źródło