Java – mockito. In easymock What is the analogy of spy / doreturn?
Imagine that I have the following courses:
public class TestClass { public class Index<X> { } public class IndexData { private final Index<?> index; private final reentrantreadwritelock lock = new reentrantreadwritelock(); public IndexData(final Index<?> index) { super(); this.index = index; } public Index<?> getIndex() { return index; } public Lock getReadLock() { return lock.readLock(); } public Lock getWriteLock() { return lock.writeLock(); } } public void add(final InputClass input) { final IndexData index = getIndex(input); final Lock lock = index.getWriteLock(); lock.lock(); try { // Do something here,which requires synchronization } finally { lock.unlock(); } } protected IndexData getIndex(final InputClass input) { // Some logic of getting the index for input return null; } }
I want to write a unit test for verification
>Index. Is used in the add method Getwritelock() (instead of index. Getreadlock()), > take lock > publish
Using mockito, I can write a test like this:
@Test public void testAddUsesWriteLock() { // Prepare final TestClass objectUnderTest = Mockito.spy(new TestClass()); final InputClass input = Mockito.mock(InputClass.class); final IndexData indexData = Mockito.mock(IndexData.class); Mockito.doReturn(indexData).when(objectUnderTest).getIndex(input); final Lock lock = Mockito.mock(Lock.class); Mockito.doReturn(lock).when(indexData).getWriteLock(); // Invoke method under test objectUnderTest.add(input); // Verify Mockito.verify(indexData).getWriteLock(); Mockito.verify(indexData,Mockito.never()).getReadLock(); Mockito.verify(lock).lock(); Mockito.verify(lock).unlock(); }
How can I do the same thing with easymock?
Specifically: how can I make the getindex method return an analog line (mockito. Doreturn (indexdata) in easymock when(objectUnderTest). getIndex(input))?
Note: you can find the code for this sample here
Solution
In the spirit of providing possible solutions (contrary to my comments above), you can try one of the following methods
Option 1
If testclass implements an interface, you can use anddelegateto() to perform similar tests. As described in this article, we discuss easymock not supporting playing
Option 2
Eliminate your need for spies by extending testclass specifically for your test requirements This is a common way to deal with legacy code bases, and you cannot change the code in the test
I will use mockito in this example so that it is consistent with your problem, but this concept works the same way as easymock
public class TestClassUsingMockito { /** We extend the original class under test so that we can override the creation of IndexData and thereby remove the responsibility of creating this object from the @Test method */ private class ClassForTesting extends TestClass { private Lock lock; private IndexData indexData; public ClassForTesting(IndexData indexData,Lock lock) { this.indexData = indexData; this.lock = lock; } @Override protected IndexData getIndex(InputClass input) { return indexData; } } /** Look Ma' no more Spys! */ @Test public void testAddUsesWriteLock() { // Prepare final Lock lock = Mockito.mock(Lock.class); final IndexData indexData = Mockito.mock(IndexData.class); Mockito.doReturn(lock).when(indexData).getWriteLock(); // ... Now use your new subclass for testing final TestClass objectUnderTest = new ClassForTesting(indexData,lock); final InputClass input = Mockito.mock(InputClass.class); // Invoke method under test objectUnderTest.add(input); // Verify Mockito.verify(indexData).getWriteLock(); Mockito.verify(indexData,Mockito.never()).getReadLock(); Mockito.verify(lock).lock(); Mockito.verify(lock).unlock(); } }
Mockito in easymock What is the analogy of spy / doreturn?
Therefore, the need for spy () called by mockito has been removed from your test
Mockito.doReturn(lock).when(indexData).getWriteLock();
It can be written in easymock
expect(indexData.getWriteLock()).andStubReturn(lock);
Easymock example of the above mockito test
public class TestClassUsingEasymock extends EasyMockSupport { private class ClassForTesting extends TestClass { private Lock lock; private IndexData indexData; public ClassForTesting(IndexData indexData,Lock lock) { this.indexData = indexData; this.lock = lock; } @Override protected IndexData getIndex(InputClass input) { return indexData; } } @Test public void testAddUsesWriteLock() { // Prepare final Lock lock = createNiceMock(Lock.class); final IndexData indexData = createNiceMock(IndexData.class); EasyMock.expect(indexData.getWriteLock()).andStubReturn(lock); // ... Now use your new subclass for testing final TestClass objectUnderTest = new ClassForTesting(indexData,lock); final InputClass input = createNiceMock(InputClass.class); lock.lock(); EasyMock.expectLastCall(); lock.unlock(); EasyMock.expectLastCall(); replayAll(); // Invoke method under test objectUnderTest.add(input); // Verify verifyAll(); } }