前言

笔者在晚期就曾纠结过这个问题,过后只是简略的了解为Mock和MockBean注解的内部依赖并不会实在执行,然而这个没有实在执行又代表哪个意思呢?那Spy实在执行的了解是如何呢?Mock和MockBean又有啥区别呢?

非实在执行:

引言:始终蛊惑执行的是mock的bean,然而不晓得为何并没有执行又进行测试呢?
其中碰到一个实例很好:

@Testpublic 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 申请@AutoConfigureMockMvcpublic 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("执行办法");就会报错,是因为它真的执行了理论的办法,并产生影响。

总结:

本周第二次写后盾登录时没有用到单元测试,而是应用了集成测试,同时在测试中使用了单元测试的形式,遇到了很多问题,然而本人查了之后对于单元测试也不再那么恐怖。