简体   繁体   English

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

[英]How can I mock a void method and leave everything else the same using mockito?

I'm using Mockito and want to do a hopefully simple thing. 我正在使用Mockito,并希望做一个希望简单的事情。 How do I mock a void method for a particular class? 如何为特定类模拟void方法? I tried ... 我试过了 ...

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

But I'm getting the compile error 但是我收到了编译错误

[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

My intention is instead of calling the normal code of CacheService.startCache, I want to call my own method, "PopulateCache.addTestEntriesToCache()". 我的意图是调用我自己的方法“PopulateCache.addTestEntriesToCache()”,而不是调用CacheService.startCache的正常代码。 How can I do this? 我怎样才能做到这一点?

Edit: Per the response given, I tried editing my class where I implement the mock, but the mock method (the doAnswer, presumably) isn't getting called ... 编辑:根据给出的响应,我尝试编辑我的类,我实现模拟,但模拟方法(大概是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 

}

Thanks, - Dave 谢谢, - 戴夫

You are making a mock for the CacheService, but you are still not returning it and using it anywhere. 您正在为CacheService进行模拟,但您仍然没有返回它并在任何地方使用它。 Instead, you are calling the real static CacheService.instance() method which will not return your mock. 相反,您正在调用真正的静态CacheService.instance()方法,该方法不会返回您的模拟。 Make you setupMockCache() return the CacheService and use it directly rather than going through the instance() method. 让setupMockCache()返回CacheService并直接使用它而不是通过instance()方法。

Also in the question title/summary, you said "leave everything else the same". 同样在问题标题/摘要中,你说“让其他一切都保持不变”。 If you mean you want the rest of CacheService to behave the same as it normaly would, then perhaps you want a partial mock, which you can do with Mockito's spy() instead of mock(). 如果你的意思是你希望CacheService的其余部分的行为与它的正常行为相同,那么也许你想要一个部分模拟,你可以用Mockito的spy()代替mock()。

Put the call to your cache in the anwser-method of this http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#12 通过此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();

Of course it doesn't work : in setupMockCache you are creating a the cache mock CacheService cs = mock(CacheService.class); 当然它不起作用:在setupMockCache你创建了一个缓存模拟CacheService cs = mock(CacheService.class); on which you define the stub. 您在其上定义存根。 But the cs instance is never passed. 但是cs实例永远不会通过。 And in initCache you are calling the setup method, but you don't get the CacheService instance, right after you wrote this statement CacheService.getInstance().startCache(); initCache您正在调用setup方法,但在编写此语句CacheService.getInstance().startCache();后,您没有获得CacheService实例CacheService.getInstance().startCache(); that will certainly create a real CacheService instance and fo course it won't use the mocked instance. 这肯定会创建一个真正的CacheService实例,当然它不会使用CacheService的实例。

I don't know what you want to do, this seems weird and wrong to mock partially a Cache in your production code! 我不知道你想做什么,在你的生产代码中部分模拟一个Cache似乎很奇怪和错误! If I were you I would create my own set of classes that will return your custom cache backed by an inherited CacheService class if necessary (this class will explicitly overide the startCache method). 如果我是你,我会创建自己的一组类,如果需要,将返回由继承的CacheService类支持的自定义缓存(此类将明确覆盖startCache方法)。

Hope that helps! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM