Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito: wait for an invocation that matches arguments

I'm writing a selenium test and verifying the server behavior with mockito. Specifically, when a button is clicked, I want to make sure the page controller calls a particular method on a dependency which I've mocked.

Because it is a selenium test, I need to wait for the mock to be invoked in another thread, so I'm using mockito timeout.

verify(myMock, timeout(5000).times(1)).myMethod("expectedArg"); 

The trouble that I'm having is that myMethod is called many times... rather than waiting for an invocation that matches the expected arguments, timeout only waits for the first invocation. If I use Thread.sleep(50000) rather than timeout(50000), it works as expected... but that's dirty so I'm hoping to avoid it.

How do I wait for myMethod to be invoked with the expected input?

like image 345
Bryan Hart Avatar asked Apr 08 '14 17:04

Bryan Hart


1 Answers

If you are able to set a fixed number of calls to expect, it can be done with an ArgumentCaptor:

import static org.hamcrest.CoreMatchers.hasItem;  @Captor ArgumentCaptor<String> arg;  @Before public void setUp() throws Exception {     // init the @Captor     initMocks(this); }  @Test public void testWithTimeoutCallOrderDoesntMatter() throws Exception {     // there must be exactly 99 calls     verify(myMock, timeout(5000).times(99)).myMethod(arg.capture());     assertThat(arg.getAllValues(), hasItem("expectedArg")); } 

Another way is to specify all the expected values to verify, but those need to be provided in the exact order that they are invoked. The difference to the above solution is that this doesn't fail even if the mock is additionally called with some non-verified arguments. In other words, no need to know the number of total invocations. Code example:

@Test public void testWithTimeoutFollowingCallsDoNotMatter() throws Exception {     // the order until expected arg is specific     verify(callback, timeout(5000)).call("firstExpectedArg");     verify(callback, timeout(5000)).call("expectedArg");     // no need to tell more, if additional calls come after the expected arg     // verify(callback, timeout(5000)).call("randomArg"); } 
like image 197
juhoautio Avatar answered Sep 20 '22 17:09

juhoautio