What is the analogue of Mockito.spy / doReturn in EasyMock?

Imagine I have the following class:

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 that checks that

  • the add method uses index.getWriteLock() (not index.getReadLock() ),
  • locks in and
  • released.

Using Mockito, I can write a test as follows:

 @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 with EasyMock?

Specific: How can I return the getIndex method in Moodle in EasyMock (string Mockito.doReturn(indexData).when(objectUnderTest).getIndex(input) )?

Note. You can find the code for this example here.

+6
source share
1 answer

In the spirit of providing a possible solution (and unlike my comments above), you can try one of the following

Option 1

If TestClass implements an interface, you can achieve a similar test using andDelegateTo () , as described in this post, which says Easymock does not support spying

Option 2

Take TestClass need for espionage by expanding TestClass specifically for your testing requirements. This is a general approach to working with legacy code bases, where you cannot modify the tested code.

I use Mockito in this example so that it is consistent with your question, however the concept will work the same with 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(); } } 

What is the analogue of Mockito.spy / doReturn in EasyMock?

So, by removing the need for Spy () in your tests, calling Mockito

 Mockito.doReturn(lock).when(indexData).getWriteLock(); 

Can be written in EasyMock as

 expect(indexData.getWriteLock()).andStubReturn(lock); 

EasyMock example of the same Mockito test above

 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(); } } 
+4
source

Source: https://habr.com/ru/post/982307/


All Articles