mock单元测试+Jacoco
参考https://www.jianshu.com/p/c68ee5d08fddhttps://www.cnblogs.com/hthuang/p/6890967.html1.普通spring的mock配置pom.xmldependency groupIdjunit/groupId artifactIdjunit/artifactId version4.12/version /dependency dependency groupIdorg.mockito/groupId artifactIdmockito-all/artifactId version1.10.19/version /dependency测试原理隔离测试主要通过Mock和InjectMocks两个注解来实现模拟与被模拟。Mock模拟出一个Mock对象对象是空的需要指明对象调用什么方法传入什么参数时返回什么值InjectMocks依赖Mock对象的类也即是被测试的类。Mock出的对象会被注入到InjectMocks对象中测试示例serviceimport com.agoura.agoura.entity.Members; import com.agoura.agoura.mapper.MembersMapper; import com.agoura.agoura.service.MembersService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; Service public class MembersServiceImpl implements MembersService { Autowired private MembersMapper membersMapper; Override public Members getMemberById(int id) { return membersMapper.selectByPrimaryKey(id); } }测试类及方法import com.agoura.agoura.entity.Members; import com.agoura.agoura.mapper.MembersMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(locations {classpath*:spring-mybatis.xml}) public class MembersServiceTest { Mock private MembersMapper membersMapper;//执行的service里面需要被mock InjectMocks Spy private MembersServiceImpl membersService; //需要执行的service Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); } Test public void testGetMembersById() { Members m new Members(3, wangwu, 1, 5, 12131232342); when(membersMapper.selectByPrimaryKey(3)).thenReturn(m); Members result membersService.getMemberById(3); System.out.println(result); assertEquals(m, result); when(membersMapper.selectByPrimaryKey(Mockito.anyInt())).thenReturn(m); result membersService.getMemberById(3); System.out.println(result); assertEquals(m, result); } }or//SpringBootTest //或者 //RunWith(SpringJUnit4ClassRunner.class) //推荐 //或者 RunWith(SpringRunner.class) public class LessonManagerTest { InjectMocks LessonManagerImpl lessonManager; Mock OrderService orderService; Mock ResumeOperateFeignClient resumeOperateFeignClient; BeforeEach public void setUp(){ //加上这个配置,可以把mock注解的类注入到 InjectMocks 类里面 MockitoAnnotations.openMocks(this); } }2.Springboot MockBean如果使用的是Springboot测试可以用MockBean更简单的写出等价的测试。RunWith(SpringRunner.class) SpringBootTest public class ServiceWithMockBeanTest { MockBean SampleDependencyA dependencyA;//需要被mock的 Autowired SampleService sampleService; //需要执行的service Test public void testDependency() { when(dependencyA.getExternalValue(anyString())).thenReturn(mock val: A); assertEquals(mock val: A, sampleService.foo()); } }项目中的codeRunWith(SpringRunner.class) SpringBootTest(classes { RunApplication.class }) //ActiveProfiles(dev) //TestPropertySource(properties {spring.profiles.activedev}) Slf4j public class ResourceServiceImplTest { Autowired private ResourceServiceImpl resourceService; //需要测试的service Autowired private ApplicationContext applicationContext; MockBean private SessionContextService sessionContextService; //ResourceServiceImpl里面需要用到的类 MockBean private AppUtil appUtil;//ResourceServiceImpl里面需要用到的类 Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); SessionContextDTO sessionContextDTO new SessionContextDTO(); sessionContextDTO.setAccountId(2980060L); sessionContextDTO.setSessionId(111); Mockito.when(sessionContextService.getContextBySessionId(Mockito.anyString())).thenReturn(sessionContextDTO); ListString goodsCodes Arrays.asList(83146244, 83137207); Mockito.when(appUtil.getGoodsCodeList(Mockito.anyString())).thenReturn(goodsCodes); Mockito.when(appUtil.getSmartGoodsCodeList(Mockito.anyString())).thenReturn(goodsCodes); Mockito.when(appUtil.getCity(Mockito.anyLong())).thenReturn(长沙); } Test public void testFillResourceForDataRec() { CardContentDTO contentDTO new CardContentDTO(); contentDTO.setResourceId(10042); String sessionId 111; try { BaseResult s new BaseResult(); resourceService.fillResource(contentDTO, sessionId, false, s); log.info(rsp error: JSONObject.toJSONString(s)); } catch (Exception e) { e.printStackTrace(); } } }1.多次调用返回不一样的值// 第一次调用返回 10 // 第一次调用返回 20 Mockito.when(data.size()).thenReturn(10, 20);3.两种单测的区别普通spring的被InjectMocks标注的字段只能被注入被mock标注的类mockbean标注的不行-- 这个用来全部做mock不会启动容器springboot的被autowired标注的字段只能被注入被mockbean标注的类mock标注的不行-- 这个用来做单元测试部分mock会启动容器4.自动回滚Junit单元测试时在测试方法中打事务注解Transactional默认会按照Rollback(true)来进行处理即使在没加注解Rollback也会对事务回滚Transactional Rollback(true) Test public void testReduce() throws Exception { ReduceReq req new ReduceReq(); req.setAccountId(3860039L); req.setCode(TaskTypeForBizCodeEnum.DKHD1228.getCode()); req.setSecretKey(TaskTypeForBizCodeEnum.DKHD1228.getSecretKey()); req.setMoney(100); req.setRequestId(123456789); req.setTaskName(task name); String recordNo healthAwardService.reduce(req); log.info(healthAwardService.reduce。rsp:{}, recordNo); Assert.assertNotNull(recordNo); }注意事项碰到过好几次了单元测试有问题1.看下public加了么2.看下TEST有么3.看下junit包是不是正确的别引用了其他的包了5.jacoco官网https://www.baeldung.com/jacoco-report-exclude生成的报告/target/site/jacoco/index.html