我如何使用mockito模拟void方法并保留其他所有内容?

时间:2012-02-10 20:41:37

标签: java mocking mockito

我正在使用Mockito并希望做一件希望简单的事情。如何为特定类模拟void方法?我试过......

    CacheService cs = mock(CacheService.class);
    when(cs.startCache()).then( PopulateCache.addTestEntriesToCache() );

但是我收到了编译错误

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:testCompile (default-testCompile) on project cme-productplus-web: Compilation failure: Compilation failure:
[ERROR] \Documents and Settings\E18538\workspace\cme-productplus-web\src\test\java\com\cme\clearing\product\server\PopulateCacheServiceImpl.java:[32,65] 'void' type not allowed here
[ERROR] \Documents and Settings\E18538\workspace\cme-productplus-web\src\test\java\com\cme\clearing\product\server\PopulateCacheServiceImpl.java:[32,20] 'void' type not allowed here

我的意图是调用我自己的方法“PopulateCache.addTestEntriesToCache()”,而不是调用CacheService.startCache的正常代码。我怎么能这样做?

编辑:根据给出的回复,我尝试编辑我的类,我实现了模拟,但是模拟方法(大概是doAnswer)没有被调用...

public class PopulateCacheServiceImpl extends RemoteServiceServlet implements PopulateCacheService {

/**
 * 
 */
private static final long serialVersionUID = 1L;

public Boolean initCache() { 
    boolean ret = false;
    try {
        setupMockCache();
        CacheService.getInstance().startCache();
        ret = true;
    } catch (Exception e) {
        e.printStackTrace(System.err);
        ret = false;
    }   // try
    return ret;
}   // initCache

private void setupMockCache() { 
    CacheService cs = mock(CacheService.class);
    try {
        doAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocation) throws Throwable {
                PopulateCache.addTestEntriesToCache();
                return null;  
            }
        }).when(cs).startCache();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}   // setupMockCache 

}

谢谢, - 戴夫

3 个答案:

答案 0 :(得分:3)

您正在为CacheService进行模拟,但您仍然没有返回它并在任何地方使用它。相反,您正在调用真正的静态CacheService.instance()方法,该方法不会返回您的模拟。让setupMockCache()返回CacheService并直接使用它,而不是通过instance()方法。

同样在标题/摘要的问题中,你说“让其他一切都保持不变”。如果你的意思是你希望CacheService的其余部分的行为与它的正常行为相同,那么也许你想要一个部分模拟,你可以用Mockito的spy()代替mock()。

答案 1 :(得分:1)

将调用放入此http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#12

的anwser方法中
    Mockito.doAnswer(new Answer<Object>() {
        public Object answer(InvocationOnMock invocation) throws Throwable {
            PopulateCache.addTestEntriesToCache()
            return null;  
        }
    }).when(cs).startCache();

答案 2 :(得分:0)

当然它不起作用:在setupMockCache中,您正在创建一个缓存模拟CacheService cs = mock(CacheService.class);,您可以在其上定义存根。但cs实例永远不会通过。 在initCache中,您正在调用安装方法,但是在您编写此语句CacheService后,您无法获得CacheService.getInstance().startCache();实例,这肯定会创建一个真实的CacheService实例,当然它不会使用模拟实例。

我不知道你想做什么,在你的生产代码中部分模拟一个Cache似乎很奇怪和错误!如果我是你,我会创建自己的一组类,如果有必要,将返回由继承的CacheService类支持的自定义缓存(此类将明确覆盖startCache方法)。

希望有所帮助!