介绍
在真实的业务场景,我们的服务经常会调用三方的接口或者内部其他服务的接口。
此时如果外部系统的接口不可用,我们就需要模拟它的返回值,如果通过在代码中硬编码的形式,会额外的增加工作量。
Mockito框架可以创建和配置mock对象.它简化了具有外部依赖的单元测试,我们可以使用Mockito针对具有外部依赖的service层进行测试。
一般来说Mockito的使用步骤:
- 将外部依赖通过Mockito进行模拟构造。
- 将构造后的依赖注入到引用它的类中。
- 为模拟的外部依赖,编写期望返回的结果。
- 正常调用需要进行单元测试的方法。
快速使用
我们使用RestTemplate模拟真实场景下微服务内部的调用。
开启注解
在setup中开启mockito的注解:MockitoAnnotations.initMocks(this)
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class BaseTest {
@Autowired
protected WebApplicationContext wac;
protected MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
MockitoAnnotations.initMocks(this);
}
}
创建需要单元测试的接口
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/testRestTemplate")
public ResponseEntity<String> test() {
return restTemplate.getForEntity("xxx", String.class);
}
}
编写单元测试
/**
* @author zhangbowen
* @since 2019/4/13
*/
@SpringBootTest(classes = TestApplication.class)
public class ApiTest extends BaseTest {
//标识该template为mock生成的
@MockBean
private RestTemplate restTemplate;
/**
* mock restTemplate 测试
*/
@Test
public void restTemplate() throws Exception {
//Mockito.when表示当执行某个方法时进行模拟
//Mockito.any()代表任意参数
//thenReturn表示期望模拟返回的结果
Mockito.when(restTemplate.getForEntity(Mockito.anyString(), Mockito.any()))
.thenReturn(new ResponseEntity<>("aaaa", HttpStatus.OK));
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders
.get("/demo/testRestTemplate");
super.buildRequest(() -> mockHttpServletRequestBuilder);
}
}
网友评论