首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Mockito对调用异步函数的函数进行单元测试

使用Mockito对调用异步函数的函数进行单元测试
EN

Stack Overflow用户
提问于 2015-12-01 18:22:24
回答 2查看 207关注 0票数 0

我有一个调用异步函数的方法:

代码语言:javascript
运行
复制
public class MyService {
  ...
  public void uploadData() {
    MyPool.getInstance().getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    boolean suc = upload();
                }
            });
        }
}

我想用Mockito对这个函数进行单元测试,我试过了:

代码语言:javascript
运行
复制
MyPool mockMyPool = Mockito.mock(MyPool.class);
ThreadPool mockThreadPool = Mockito.mock(ThreadPool.class);
ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);

when(mockMyPool.getThreadPool()).thenReturn(mockThreadPool);
MyService service = new MyService();

// run the method under test
service.uploadData();

// set the runnableCaptor to hold your callback
verify(mockThreadPool).execute(runnableCaptor.capture());

但是我得到了一个错误:

代码语言:javascript
运行
复制
org.mockito.exceptions.verification.WantedButNotInvoked: 
Wanted but not invoked:
threadPool.execute(
    <Capturing argument>
);

为什么会出现这个错误,如何使用Mockito对uploadData()函数进行单元测试?

EN

回答 2

Stack Overflow用户

发布于 2015-12-01 20:06:52

好吧,我自己想出了一个办法,因为MyPool是一个单例。我添加了一个公共函数setInstance(mockedInstance)来将模拟的实例传递给MyPool。然后,它就可以工作了。我知道这有点“脏”,但如果你有更好的解决方案,请让我知道。谢谢!

票数 0
EN

Stack Overflow用户

发布于 2015-12-02 03:13:02

除了您发现的保留MyPool或ThreadPool字段的DI方法之外,您还可以稍微重构一下,以允许在您的方法中注入依赖项

代码语言:javascript
运行
复制
public class MyService {
  ...
  public void uploadData() {
    uploadData(MyPool.getInstance().getThreadPool());
  }

  /** Receives an Executor for execution. Package-private for testing. */
  void uploadData(Executor executor) {
    executor.execute(new Runnable() {
      @Override public void run() {
        boolean suc = upload();
      }
    });
  }
}

这可能更简洁,因为它将ThreadPool降低到所需的抽象级别(执行器),这意味着您只模拟一个方法接口,而不是ThreadPool (我假设它与ThreadPoolService相关;否则,您也可以接受ThreadPool )。按照官方说法,您的uploadData()将是未经测试的,但您可以轻松而彻底地测试uploadData(Executor)uploadData(ThreadPool),这是最有可能崩溃的移动部分。

包私有技巧确实依赖于您的代码和测试在同一个包中,尽管它们可能在不同的源文件夹中;或者,您可以只将接收ThreadPool的调用作为公共API的一部分,这将在以后提供更大的灵活性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34017958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档