mock的意义
在微服务盛行的当下,开发过程中往往出现A应用中某功能的实现需要调用B应用的接口,无论使用RPC还是restful都需要B应用提供接口的实现整个开发工作才能继续进行。从而导致A应用的开发停滞,整个系统的开发效率降低。
这时该mock出场了。通过模拟一个接口的实现,让A应用假设能够正常调用B应用,并得到相应的返回值或产生指定类型的异常。
待B应用的接口实现开发完成再取消mock,实现真正的调用。
以下演示在spring boot test中使用mockito模拟接口实现的使用方式。
引入相关依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
待测试接口
public interface UserService { public User findOne(Long id); }
待测试POJO
public class User { private Long id; private String name; private Date createDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } }
编写测试类
import static org.mockito.Mockito.when; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = { AppStart.class }) public class TestUserService { @Mock private UserService userService; private Logger logger = LoggerFactory.getLogger(getClass()); @Before public void setUp(){ User mockUser = new User(); mockUser.setName("john"); mockUser.setId(1L); mockUser.setCreateDate(new Date()); when(userService.findOne(1L)).thenReturn(mockUser); } @Test public void findOneTest() { User user = userService.findOne(1L); logger.info("user.name = {}",user.getName()); Assert.assertEquals(user.getName(), "john"); } }
总结
- 使用@Mock注解对测试接口进行修饰。该注解位于org.mockito.Mock中
- 使用when().thenReturn()方法指定测试接口中某方法的返回值。(也可以指定抛出的异常类型等)。