Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using easymock in multithreading

I want to test that some method would be recalled on failing. Calling executed in separate thread. So I write code like this

final Foo mock = createStrictMock(Foo.class);

mock.bar();
expectLastCall().andThrow(new RuntimeException("TEST EXCEPTION"));
mock.bar();
replay(mock);

doStuff();
sleepSomeTime(); //Pretty dirty. But I need to test it in multithreading.
verify(mock);

And test passed. But I did not implement recall yet.

To make test fail, I replaced

 mock.bar();
 expectLastCall().andThrow(new RuntimeException("TEST EXCEPTION"));

with

 mock.bar();
 expectLastCall().andAnswer(new IAnswer<Void>() {
        @Override
        public Void answer() throws Throwable {
            sleepSomeTime();
            throw new RuntimeException("TEST EXCEPTION");
        }
    });

But I don't like adding sleepSomeTime all around my tests. Beside that, I don't actually understand while it helps in this particular case. So,

Why adding delay helped?

What the right way to do such stuff?

like image 864
Stan Kurilin Avatar asked May 20 '13 14:05

Stan Kurilin


1 Answers

My approach has been to use locks. There isn't quite enough info in your post to show something definitive, but it'd probably look something like this:

final Lock lock = new Lock();
lock.lock();
expectLastCall().andAnswer(new IAnswer<Void>() {
    @Override public Void answer() throws Throwable {
        lock.unlock();
        throw new RuntimeException("TEST EXCEPTION");
    }
});     
doStuff();
lock.lock();
verify(mock);

The gist here is the second lock() invocation is blocked until the unlock in your mock frees up the lock.

like image 136
Chris Kessel Avatar answered Oct 13 '22 19:10

Chris Kessel