Jak zrobić mock to void metody z mockito
Jak mockować metody z void return type?
Zaimplementowałem wzór obserwatora, ale nie mogę wyśmiewać go z Mockito, bo nie wiem jak.
Próbowałem znaleźć przykład w Internecie, ale się nie udało.Moja klasa wygląda jak
public class World {
List<Listener> listeners;
void addListener(Listener item) {
listeners.add(item);
}
void doAction(Action goal,Object obj) {
setState("i received");
goal.doAction(obj);
setState("i finished");
}
private string state;
//setter getter state
}
public class WorldTest implements Listener {
@Test public void word{
World w= mock(World.class);
w.addListener(this);
...
...
}
}
interface Listener {
void doAction();
}
System nie jest uruchamiany za pomocą mocka. =( Chcę pokazać wyżej wymieniony stan systemu. I dokonać twierdzenia według nich.
10 answers
[[10]}spójrz na Mockito API docs . Jak wspomina dokument linkowany (Punkt # 12) można użyć dowolnego z doThrow()
,doAnswer()
,doNothing()
,doReturn()
rodzina metod od Mockito framework do mock void methods.
Na przykład,
Mockito.doThrow(new Exception()).when(instance).methodName();
Lub jeśli chcesz połączyć to z zachowaniem obserwacji,
Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();
Zakładając, że patrzysz na wyśmiewanie settera setState(String s)
w świecie klas poniżej, kod używa metody doAnswer
do wyśmiewania setState
.
World mockWorld = mock(World.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockWorld).setState(anyString());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 03:41:18
Myślę, że znalazłem prostszą odpowiedź na to pytanie, aby wywołać prawdziwą metodę tylko dla jednej metody (nawet jeśli ma void return) możesz to zrobić:
Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();
Lub, można wywołać prawdziwą metodę dla wszystkich metod tej klasy, robiąc to:
<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-10 20:41:15
Dodając do tego, co powiedział @sateesh, gdy chcesz wyśmiewać metodę void, aby zapobiec wywołaniu testu, możesz użyć Spy
w ten sposób:
World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();
Jeśli chcesz uruchomić test, upewnij się, że wywołujesz metodę w teście na obiekcie spy
, a nie na obiekcie world
. Na przykład:
assertEquals(0,spy.methodToTestThatShouldReturnZero());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 12:07:06
Rozwiązaniem tak zwanego problemu jest użycie spy
Mockito.Szpieg(...) zamiast a mock
Mockito.mock(..).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 15:47:25
Po Pierwsze: należy zawsze importować Mockito static, w ten sposób kod będzie znacznie bardziej czytelny (i intuicyjny):
import static org.mockito.Mockito.*;
Za częściowe wyśmiewanie i zachowanie oryginalnej funkcjonalności na reszcie Mockito oferuje "szpiega".
Możesz go użyć w następujący sposób:
private World world = spy(World.class);
Aby wyeliminować metodę z wykonania można użyć czegoś takiego:
doNothing().when(someObject).someMethod(anyObject());
Aby nadać pewne niestandardowe zachowanie metodzie, użyj "when" z "thenReturn":
doReturn("something").when(this.world).someMethod(anyObject());
Więcej przykłady proszę znaleźć próbki mockito w dokumencie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-11 16:06:47
Jak wyśmiewać metody void za pomocą mockito - są dwie opcje:
-
doAnswer
- jeśli chcemy, aby nasza metoda wyśmiewana void zrobiła coś (wyśmiewała zachowanie pomimo bycia void). -
{[2] } - wtedy jest
Mockito.doThrow()
Jeśli chcesz wyrzucić wyjątek z metody mocked void.
Poniżej znajduje się przykład, jak go używać (nie jest to idealna podstawa, ale po prostu chciała zilustrować podstawowe użycie).
@Test
public void testUpdate() {
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {
Customer customer = (Customer) arguments[0];
String email = (String) arguments[1];
customer.setEmail(email);
}
return null;
}
}).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("[email protected]", "[email protected]");
//some asserts
assertThat(customer, is(notNullValue()));
assertThat(customer.getEmail(), is(equalTo("[email protected]")));
}
@Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {
doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("[email protected]", "[email protected]");
}
}
Możesz znaleźć więcej szczegółów na temat tego, jak mock i test void metody z Mockito w moim poście Jak Mockito (obszerny poradnik z przykładami)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 02:52:16
Dodanie kolejnej odpowiedzi do grupy (nie zamierzona gra słów)...
Musisz wywołać metodę doAnswer, jeśli nie możesz\nie chcesz używać spy ' S. jednak niekoniecznie musisz toczyć własną ODPOWIEDŹ. Istnieje kilka domyślnych implementacji. W Szczególności, CallsRealMethods .
W praktyce wygląda to mniej więcej tak:
doAnswer(new CallsRealMethods()).when(mock)
.voidMethod(any(SomeParamClass.class));
Lub:
doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
.voidMethod(any(SomeParamClass.class));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-31 12:31:16
Myślę, że Twoje problemy są spowodowane strukturą testu. Trudno mi było mieszać szyderstwa z tradycyjną metodą implementacji interfejsów w klasie testowej(tak jak to zrobiłeś tutaj).
Jeśli zaimplementujesz słuchacza jako makietę, możesz zweryfikować interakcję.
Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();
To powinno cię zadowolić, że "świat" postępuje właściwie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-07 07:56:30
W Javie 8 może to być nieco czystsze, zakładając, że masz statyczny import dla org.mockito.Mockito.doAnswer
:
doAnswer(i -> {
// Do stuff with i.getArguments() here
return null;
}).when(*mock*).*method*(*methodArguments*);
return null;
jest ważne i bez niego kompilacja nie powiedzie się z dość niejasnymi błędami, ponieważ nie będzie w stanie znaleźć odpowiedniego nadpisania dla doAnswer
.
Na przykład ExecutorService
, który natychmiast wykonuje dowolne Runnable
przekazane do execute()
, może być zaimplementowane za pomocą:
doAnswer(i -> {
((Runnable) i.getArguments()[0]).run();
return null;
}).when(executor).execute(any());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-04 09:43:54
@ashley : działa dla mnie
public class AssetChangeListenerImpl extends AbstractAssetChangeListener implements AssetChangeListener { @Override public void onChangeEvent(final EventMessage message) throws EventHubClientException { execute(message); } } } public class AbstractAssetChangeListener { protected void execute( final EventMessage message ) throws EventHubClientException { executor.execute( new PublishTask(getClient(), message) ); } } @RunWith(MockitoJUnitRunner.class) public class AssetChangeListenerTest extends AbstractAssetChangeListenerTest { public void testExecute() throws EventHubClientException { EventMessage message = createEventMesage(EventType.CREATE); assetChangeListener.execute(message); verify(assetChangeListener, times(1)).execute(message); } }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-21 11:15:56