背景
团队推行单元测试,需要对主要逻辑serice层做单元测试,但是有些service会有外部接口调用或上游接口调用,而因为环境问题,这部分接口又无法掉通,为了解决这个问题,我接入了Mockito。
使用
1. 添加依赖
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
2. 具体使用
- @InjectMocks修饰需要测试的类
- @Mock修饰需要mock掉的类
- 初始化mock注解
- 声明调用特定方法时,传入指定参数,返回指定指
- when(xxx.yyy(zzz)).thenReturn(aaa); // 当调用xxx.yyy()方法且入参是zzz时,返回aaa;如果入参不是zzz,则返回null。
- when(xxx.yyy()).thenAnswer(t -> {});// 当调用xxx.yyy()方法时,没有返回值,执行一个自定义的函数体。
- 如果被mock的类在需要测试的类中是一个私有的字段,则需要反射修改私有字段的值,将其替换成mock代理类 ReflectionTestUtils.setField(testObject, “field”, mockObject);
- test原本需要测试的方法
例:
service调用链:
@Service
public class MerchantDataService {
@Reference
private IMerchantUserService merchantUserService;
public Object save(Object obj) {
xxxxxx;
ResponseEntity = merchantUserService.insert(xxxx);
xxxxxx;
return xxx;
}
}
单元测试使用:
@SpringBootTest(classes = ApplicationStartup.class)
@ActiveProfiles("test")
public class MerchantDataServiceTest extends AbstractTransactionalTestNGSpringContextTests {
@InjectMocks
@Autowired
private IMerchantDataService merchantDataService;
@Mock
private IMerchantUserService merchantUserService;
@BeforeMethod(alwaysRun = true)
public void initMock() {
// 初始化mock注解
MockitoAnnotations.initMocks(this);
ResponseEntity resp = new ResponseEntity().setStatus(Status.SUCCESS);
// 当执行merchantUserService.insert方法时,返回申明的对象
when(merchantUserService.insert(new xxxx())).thenReturn(resp);
}
@Test
public void testSave() {
Object obj = new Object();
Object resultObj = merchantDataService.save(obj);
Assert.assertTrue(respOthers.success());
}
}
以上