Can I instruct a mock to delay the response so that I can test concurrent access scenarios deterministically ?

13,352 views
Skip to first unread message

David Nouls

unread,
Jan 4, 2011, 10:40:31 AM1/4/11
to moc...@googlegroups.com
Hi,
 
This might be a newbie question since I am only experimenting with Mockito for a week or 2, but I did not find much in the provided Javadocs or wikis that might give me a clue on how to simulate this.
 
I have a cache class that I need to test, which allows me to specify a strategy class to load a new value, determine maximum age and how to create clones to avoid cache poisoning with modifable objects. The class under test is the Cache, and I want to stub the strategy. The load method is the one that I want to change so that it takes some time to give me response (simulating potential long delays in getting data in the cache).
 
I need to check that when multiple threads ask for the same key while a slow load of the key's value is ongoing, that the load is really only performed once and that all threads get the correct response.
 
Is there a functionality where I can instruct a stub to wait for x milliseconds before returning the result to a call ?
 
something like:
final CacheStrategy mock = mock( CacheStrategy.class );
when(mock.load("a")).sleep(5000).thenReturn("ABCD1234");
 
final CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
 new Thread() {
   public void run() {
      assertEquals("ABCD1234", cache.get("key"));
      latch.countDown();
   }
 }.start();
}
latch.await();
 
// did the test really only invoke the load once.
verify(mock, times(1)).load("key");
 
An alternative would be that I could use a Callable to define the body of one method on the stub.
 
Something like:
when(stub.load("key")).thenInvoke( new Callable<String>() {
  public String call() {
    ..... (wait for a lock or some other signal that I raise in my test case) ...
    return "ABCD1234";
  }
});
 
I need this to stage certain multithreading scenarios.
 
All this can be done by creating a manual stub but I wonder if Mockito has some support for this ? Or should I think about the testing in a different way ?
 
David Nouls

Kristofer Karlsson

unread,
Jan 4, 2011, 10:50:15 AM1/4/11
to moc...@googlegroups.com
This should work:
when(mock.load("a")).thenAnswer(new Answer() {
   public Object blabla() {
     Thread.sleep(5000);
     return
"ABCD1234";
   }
});
 

--
You received this message because you are subscribed to the Google Groups "mockito" group.
To post to this group, send email to moc...@googlegroups.com.
To unsubscribe from this group, send email to mockito+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mockito?hl=en.

David

unread,
Jan 4, 2011, 10:55:08 AM1/4/11
to moc...@googlegroups.com
It was a newbie question! Thanks!

I am really starting to love Mockito.

David

Holger Hoffstätte

unread,
Jan 4, 2011, 10:58:33 AM1/4/11
to moc...@googlegroups.com
David,

it's not entirely what you asked for but could get you on the right
path: http://code.google.com/p/awaitility/

Awaitility saves an insane amount of usually very fragile sleeping &
latch-countdown code that people needlessly inflict on themselves.

good luck!

Holger

Brice Dutheil

unread,
Jan 17, 2011, 9:07:44 AM1/17/11
to moc...@googlegroups.com
Just a thought: I really like the way to indicate time stuff while stubbing.

Inspired on David's proposition but made a bit more fluent :
when(mock.load("a")).thenReturn("ABCD1234").after(5000);


It could saves users like David to write an answer for this case.


-- 
Bryce


2011/1/4 Holger Hoffstätte <holger.ho...@googlemail.com>

Malte Finsterwalder

unread,
Jan 17, 2011, 1:15:08 PM1/17/11
to moc...@googlegroups.com
just a side note:
delays in tests are usually not a good idea.
Rather use explicit synchronization with latches or alike and await.
Delays usually leads to fragile tests that sometimes fail.
And also the delays are usually larger than needed, so it slows down your tests.

Greetings,
Malte

Brice Dutheil

unread,
Jan 18, 2011, 6:18:52 AM1/18/11
to moc...@googlegroups.com
Good point Malte.



-- 
Bryce



--

Johan Haleby

unread,
Jan 18, 2011, 9:08:35 AM1/18/11
to moc...@googlegroups.com
Probably off topic but when it comes to cases where you need to synchronize on some state it's usually much more simple to use something like Awaitility instead of writing latches. You will loose a couple of milliseconds on each the test but I think that in most cases this is negligible.

/Johan


--
Reply all
Reply to author
Forward
0 new messages