java – EasyMock中Mockito.spy/doReturn的类比是什么?

想象一下,我有以下课程:
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;
    }
}

我想编写一个单元测试,用于验证

>在add方法中,使用了index.getWriteLock()(而不是index.getReadLock()),
>采取锁定
>发布.

使用Mockito我可以写一个这样的测试:

@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();
}

我怎么能用EasyMock做同样的事情?

具体:我怎样才能使getIndex方法在EasyMock中返回一个模拟(行Mockito.doReturn(indexData).when(objectUnderTest).getIndex(input))?

注意:您可以找到此示例here代码.

解决方法

本着提供可能解决方案的精神(与我上面的评论相反),您可以尝试以下方法之一

选项1

如果TestClass实现了一个接口,你可以使用andDelegateTo()进行类似的测试,如本文所述,讨论的是Easymock not supporting spying

选项2

通过专门针对您的测试要求扩展TestClass,消除您对间谍的需求.这是处理遗留代码库的常用方法,您无法更改测试中的代码.

我将在这个示例中使用Mockito,以便它与您的问题保持一致,但是这个概念与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(); 
    }
}

EasyMock中Mockito.spy / doReturn的类比是什么?

因此,在您的测试中删除了对Mockito调用的Spy()的需求

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

可以用EasyMock编写

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

以上Mockito测试的EasyMock示例

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

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...