运行环境:
jdk1.8 junit spring-test
一、背景
最近公司的项目的集成测试遇到一个问题,单元测试方法中,用Mockito.verify对依赖服务进行Mockito.times()调用次数验证时,总是处于不稳定的状态,偶尔会出现不符合预期的情况。验证的情况如下:
Mockito.verify(testService, Mockito.times(1)).printHelloWord();
这里对出现问题的程序现状做个说明:
1.1 集成测试插件的配置情况:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<forkCount>4</forkCount>
</configuration>
</plugin>
1.2 依赖服务类ITestService如下:
public interface ITestService {
String printHelloWord();
}
1.3 mock的bean配置服务如下所示:
@Configuration
public class CreateBeanFactory {
private final Logger logger = LoggerFactory.getLogger(CreateBeanFactory.class);
@Bean
public ITestService createTestService() {
ITestService testService = Mockito.mock(ITestService.class);
logger.info("线程:{}, hashcode:{}", Thread.currentThread().getName(), testService.hashCode());
return testService;
}
1.4 集成测试的抽象服务类如下:
RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath*:spring-*.xml" })
public class SpringBaseServiceTest {
@Resource
private ITestService testService;
@After
public void clearContext() {
// 执行完单测后对单测依赖的mock服务进行重置
Mockito.reset(testService);
}
}
1.5 单测类Test1如下:
public class Test1 extends SpringBaseServiceTest {
private final Logger logger = LoggerFactory.getLogger(Test1.class);
@Resource
private ITestService testService;
@Test
public void testPrintStopWord() {
Mockito.when(testService.printHelloWord()).thenReturn("Test1 stop word");
logger.info("test1 print:{}", testService.printHelloWord());
Mockito.verify(testService, Mockito.times(1)).printHelloWord();
}
@Test
public void testPrintHelloWord() {
Mockito.when(testService.printHelloWord()).thenReturn("Test1 Hello word");
logger.info("test1 print:{}", testService.printHelloWord());
Mockito.verify(testService, Mockito.times(1)).printHelloWord();
}
}
1.6 单测类Test2如下:
public class Test2 extends SpringBaseServiceTest {
private final Logger logger = LoggerFactory.getLogger(Test2.class);
//记录定时任务执行几次了
private static int count = 0;
private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
@Resource
private ITestService testService;
@Test
public void testPrintBaby() {
Mockito.when(testService.printHelloWord