共计 2758 个字符,预计需要花费 7 分钟才能阅读完成。
前言
笔者在晚期就曾纠结过这个问题,过后只是简略的了解为 Mock 和 MockBean 注解的内部依赖并不会实在执行,然而这个没有实在执行又代表哪个意思呢?那 Spy 实在执行的了解是如何呢?Mock 和 MockBean 又有啥区别呢?
非实在执行:
引言:始终蛊惑执行的是 mock 的 bean,然而不晓得为何并没有执行又进行测试呢?
其中碰到一个实例很好:
@Test | |
public void mockitoTest(){ | |
// 生成一个 mock 对象 | |
List<String> mockString = Mockito.mock(List.class); | |
// 打印 mock 对象的类名,看看 mock 对象为何物 | |
System.out.println(mockString.getClass().getName()); | |
// 操作 mock 对象 | |
mockString.add("0"); | |
mockString.get(0); | |
// 此时必定如果为实在执行,那么以后应该没有数据 | |
mockString.clear(); | |
//verify 验证,mock 对象是否产生过某些行为 | |
// 如果验证不通过,Mockito 会抛出异样 | |
Mockito.verify(mockString).add("one"); | |
Mockito.verify(mockString).get(0); | |
// 指定 mock 办法,获取一个不存在的数据,如果实在执行,那么应该报错 | |
Mockito.when(mockString.get(1)).thenReturn("执行胜利"); | |
// 这里打印出“13”(但咱们晓得 mockedList 理论是没有下标为 1 的元素,这就是 mock 的性能)System.out.println(mockString.get(1)); | |
} |
Mock 和 MockBean
之前了解:二者用法简直雷同,只是初始化的时候有所不同。
当初了解:二者初始化 mock 形式类似,然而二者适宜的场景却有很大区别
遇到问题:
笔者将 MockBean 改为 Mock 后报错:
@SpringBootTest | |
// 用于进行模仿的 HTTP 申请 | |
@AutoConfigureMockMvc | |
public class RepeaterControllerTest extends ControllerTest {private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |
@Autowired | |
RepeaterController repeaterController; | |
@Autowired | |
protected MockMvc mockMvc; | |
@Mock | |
RepeaterService repeaterService; | |
private static final String baseUrl = "/repeater"; | |
/** | |
* 取得一个中继器. | |
* | |
* @return 中继器. | |
*/ | |
public static Repeater getOneRepeater() {Repeater repeater = new Repeater(); | |
repeater.setId(new Random().nextInt()); | |
repeater.setType((byte) (new Random().nextInt() % 127)); | |
repeater.setCreationTime(new Timestamp(System.currentTimeMillis())); | |
repeater.setLastOnLineTime(new Timestamp(System.currentTimeMillis())); | |
repeater.setMonitors(new ArrayList<>()); | |
repeater.setSpec(new net.bytebuddy.utility.RandomString().nextString()); | |
repeater.setPosition(new RandomString().nextString()); | |
repeater.setReturnValue(new Random().nextLong()); | |
repeater.setLatitude(BigDecimal.valueOf(Math.random())); | |
repeater.setLongitude(BigDecimal.valueOf(Math.random())); | |
return repeater; | |
} | |
@Test | |
void getById() throws Exception {Repeater repeater = getOneRepeater(); | |
Mockito.doReturn(repeater).when(this.repeaterService).getById(Mockito.eq(repeater.getId())); | |
String url = baseUrl + "/" + repeater.getId().toString(); | |
this.mockMvc.perform(MockMvcRequestBuilders.get(url)) | |
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(repeater.getId())) | |
.andExpect(MockMvcResultMatchers.jsonPath("$.position").exists()) | |
.andExpect(MockMvcResultMatchers.status().isOk()); | |
} |
mock 没有失效,执行的仍然是实在 service:
原来也有人遇到这种问题:
1.Mock 和 Mockito 更适宜单元测试,并不能将 mock 的 bean 等装入到到整个上下文,MockBean 更适宜集成测试,MockBean 能将 mock 的 bean 加到上下文中。
2. 应用 MockBean 则必须要起 spring 环境,不利于单元测试的执行效率,应用 mockito 或 mock 的形式更好。
Spy
之前写过对于它的 ppt,过后感觉了解比拟艰难,然而当了解了不实在执行之后,了解它可能更加轻松。
spy 翻译即为“特务 ”,例如上文提到的例子mockString.add(“0”),在 mock 办法下,它并不会真正存起来,然而 spy 办法就真的会。当 mockString.clear(),之后,咱们再执行Mockito.when(mockedList.get(1)).thenReturn(“ 执行办法 ”); 就会报错,是因为它真的执行了理论的办法,并产生影响。
总结:
本周第二次写后盾登录时没有用到单元测试,而是应用了集成测试,同时在测试中使用了单元测试的形式,遇到了很多问题,然而本人查了之后对于单元测试也不再那么恐怖。