// 一个executor,和普通定义线程池一样(此处是spring自带,@Scheduled注解用到的全局线程池)
@Resource
private ThreadPoolTaskExecutor executor;
// 另一个需要装配的假定的服务
@Resource
private AnotherService anotherService;
// CompletableFuture,需要被测试的方法
public String getProductBillSummaryList(String input) {
// 异步操作
CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(
() -> anotherService.someMethod(input), executor);
// 等待执行完毕
CompletableFuture.allOf(resultFuture).join();
try {
String s = resultFuture.get();
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
return null;
我们对这个方法单元测试,大概率就直接写成:
@Mock
private AnotherService anotherService;
@InjectMocks
private ProductTransactionSearchServiceImpl productTransactionSearchService;
@Test
public void getProductBillSummaryList() {
Mockito.when(anotherService.someMethod(Mockito.any())).thenReturn("mockString");
String res = productTransactionSearchService.getProductBillSummaryList("input");
Assert.assertNull(res);
这样会导致Completable的线程不运行,一直阻塞在红色箭头指示的地方:
等待线程执行完毕。然而线程并没有执行。
此时需要模拟并驱动异步线程的执行,因此需要这样写:
@Mock
private AnotherService anotherService;
// 需要增加这个executor的mock
@Mock
private ThreadPoolTaskExecutor executor;
@InjectMocks
private ProductTransactionSearchServiceImpl productTransactionSearchService;
@Test
public void getProductBillSummaryList() {
Mockito.when(anotherService.someMethod(Mockito.any())).thenReturn("mockString");
// 新增对异步线程里面Runnable方法的驱动
Mockito.doAnswer(
(InvocationOnMock invocation) -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
).when(executor).execute(Mockito.any(Runnable.class));
String res = productTransactionSearchService.getProductBillSummaryList("input");
Assert.assertNull(res);
这样就mock了对Runnable方法的运行(就是执行run方法,只要有调用就run,不阻塞)
运行单测就可以正常通过了。
java - CompletableFuture usability and unit test - Stack Overflow
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java..
static void runAsyncExample() {
CompletableFuture cf = CompletableFuture.runAsync(() -> {
assertTrue(Thread.currentThread().isDaemon());
randomSleep();
assertFalse(cf.isDone());
sleepEnough();
Java: jdk1.8.0_144
2. 背景
Java多线程执行任务时,Logback输出的主线程和各个子线程的业务日志需要区分时,可以根据线程池和执行的线程来区分,但若要把它们联系起来只能根据时间线,既麻烦又无法保证准确性。
2018-10-27 23:09:22 [INFO][com.lxp.tool.log.LogAndCatchExceptionRunnableTest][...
Mockito是一种mock工具/框架。我理解EasyMock有点过时了,Mockito是现在比较流行的。
什么是mock?说的直白一点,大家都知道unit test应该是尽可能独立的。对一个class的unit test不应该再和其他class有任何交互。
现在有一个类,扫描一个目录并将找到的文件都上传到FTP server。该类对于不同的FTP响应(找不到FTP server 或
在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,记录Log,文件系统之类的)。而我们没法控制这些外部依赖的对象。为了 在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,记录Log,文件系统之类的)。而我们没法控制这些外部依赖的对象。为了解决这个问题,我们需要用到Stub和Mock来模拟这些外部依赖的对象,从而控制它们 实例 Analyze类会检查filename的长度,如果小于8,我们就会使用一个实现IWebService的类来记录错误. 我们需要给Analyze方法写单元测试
Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构。然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编写出容易测试的代码不但对开发人员的设计编码要求很高,而且代码中的各种依赖也常常为单元测试带来无穷无尽的障碍。令人欣慰的是开源社区各种优秀的Mock框架让单元测试不再复杂,本文简单介绍EasyMock,PowerMock等的基本常用用法。Mock说白了就是打桩(Stub)或则模拟,当你调用一个不好在测试中创建的对象时,Mock框架为你模拟一个和真实对象类似的替身来完成相应的行为。使用如下方式在Mav
数据类型、模型或节点——这些都只是mock对象可承担的角色。但mock在单元测试中扮演一个什么角色呢?有时,你需要为单元测试的初始设置准备一些“其他”的代码资源。但这些资源兴许会不可用,不稳定,或者是使用起来太笨重。你可以试着找一些其他的资源替代;或者你可以通过创建一个被称为mock的东西来模拟它。Mocks能够让我们模拟那些在单元测试中不可用或太笨重的资源。在Python中创建mock是通过Mock模块完成的。你可以通过每次一个属性(one-attribute-at-a-time)或一个健全的字典对象或是一个类接口来创建mock。你还可以定义mock的行为并且在测试过程中检查它的使用。让我们
方法返回值不是Future类型的,被执行时,会立即返回,并且无法获取方法返回值,如:
@Async
public void log(String msg) throws InterruptedException {
System.out.println(“开始记录日志,” .