單元測試和mock的使用


單元測試

在導師公司打工,做了一個版本,技術上雖然沒學到什么新東西,但是至少明白公司開發的各個流程,尤其是在提測階段十分痛苦。一個bug反復出現,不停的修改,不停的調試,十分折騰。總結了一下異常處理沒有放到controller層,log的使用還不夠,另外明白了單元測試的重要性。從前到后找bug實在是太過痛苦,應當用單元測試把bug扼殺在搖籃里。特此總結單元測試的方法和用到的技術,爭取下一個版本做到0bug提測。

包結構規范

單元測試包結構和源碼結構保持一致

命名規范

文件名

被測試文件名+Test

方法名

test+方法名+情況說明

不同單元測試類規范

以下所有的單元測試都要使用assert進行斷言,要注意分支覆蓋率盡可能提高,基層基礎測試類

 

基礎測試類,用於啟動Springboot環境

@RunWith(SpringRunner.class)
@SpringBootTest
public class MallProductApplicationTests {
@Before
public void setup() {
你的裝載邏輯
}
}

setup方法

每一個測試類都要有一個setup方法並用@Before注解,該方法用於裝載測試時需要的屬性

Controller層

使用MockMvc模擬http請求(見后面教程)

public class TestAttrController extend MallProductApplicationTests{
@Test
public void AttrAddTest() {
使用MockMVC來構造請求
}
}

Service層

注意斷言即可

Dao層

注意加上注解@RollBack防止數據庫污染,整個類加上@Transactional注解

Mock的使用

mock主要是在某個接口還尚未實現或者難以調用時來產生一個臨時的實現類

MockMVC

MockMVC是Controller層測試時用於構造http請求模擬網絡環境時用到的。由spring-test提供。在json請求場景中使用方法如下

Get請求示例

@WebAppConfiguration
public class MockTest extends GulimallProductApplicationTests {
  private MockMvc mockMvc;
  @Autowired
  private WebApplicationContext wac;
  @Before
  public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
  }

  @Test
  public void testMockMvc() throws Exception {
      MvcResult result = mockMvc.perform(
              MockMvcRequestBuilders.get("/product/category/list"))
              .andExpect(MockMvcResultMatchers.jsonPath("$.code")//斷言json返回值
                      .value(200))
              .andReturn();
      String contentAsString = result.getResponse().getContentAsString();
      System.out.println(contentAsString);
  }
}

 

說明:setup用於向mockMvc傳入當前web環境,可以使用mockmvc的.andExpect來進行斷言,一般在json返回值中使用MockMvcResultMatchers.jsonPath靜態方法斷言json中的某個值是否滿足,也可以通過下面的

result.getResponse().getContentAsString();方法直接得到json字符串做后續處理

post請求示例

    @Test
  public void testMockMvcPost() throws Exception {
      AttrGroupDto attrGroupDto = new AttrGroupDto();
      attrGroupDto.setAttrGroupName("a");
      attrGroupDto.setCatelogId(1L);
      attrGroupDto.setSort(1);
      attrGroupDto.setAttrGroupName("bb");
      attrGroupDto.setIcon("123123");
      MvcResult result = mockMvc.perform(
              MockMvcRequestBuilders.post("/product/attrgroup/add")
              .content(JSON.toJSONString(attrGroupDto)).contentType(MediaType.APPLICATION_JSON))
              .andReturn();
      System.out.println(result.getResponse().getContentAsString());
  }

使用mockito構造接口

Mockito已經包含在了springboot-test-starter里不需要額外引入

public class MockTest {
  AttrDao attrDao;
  @Before
  public void setup() {
      //初始化所有由mokito注解標注的對象
      MockitoAnnotations.initMocks(this);
      //mock AttrDao接口
      attrDao = Mockito.mock(AttrDao.class);
      AttrEntity attrEntity = new AttrEntity();
      attrEntity.setAttrId(10L);
      //定義行為
      Mockito.when(attrDao.selectAttrById(1L)).thenReturn(attrEntity);
  }
  @Test
  public void testMock() {
      AttrEntity attrEntity = attrDao.selectAttrById(1L);
      System.out.println(attrEntity);
  }
}

說明:首先需要裝載接口類,然后用Mockito.when().thenReturn方法定義接口中方法的行為即可實現mock調用

也可以使用注解注入

public class MockTest {
  @Mock
  AttrDao attrDao;
  @Before
  public void setup() {
      //初始化所有由mokito注解標注的對象
      MockitoAnnotations.initMocks(this);
      //注解注入就不需要這句了
      //attrDao = Mockito.mock(AttrDao.class);
      AttrEntity attrEntity = new AttrEntity();
      attrEntity.setAttrId(10L);
      //定義行為
      Mockito.when(attrDao.selectAttrById(1L)).thenReturn(attrEntity);
  }
  @Test
  public void testMock() {
      AttrEntity attrEntity = attrDao.selectAttrById(1L);
      System.out.println(attrEntity);
  }
}

 

Assert的使用

java自帶的關鍵字assert十分僵硬,只能傳入一個boolean值,而且斷言失敗后直接就推出了rollback也不能回滾,因此最好用junit中的Assert類

assertEqual

判斷兩者是否一致

    @Test
  public void assertEqualTest() {
      // 成功
      Assert.assertEquals(1L, 1L);
      // 失敗
      Assert.assertEquals(1L, 2L);
      int[] a1 = new int[]{1,2,3};
      int[] a2 = new int[]{1,2,3};
      int[] a3 = new int[]{2,3,4};
      // 成功
      Assert.assertArrayEquals(a1, a2);
      //失敗
      Assert.assertArrayEquals(a1, a3);
  }

assertTrue, assertFalse

直接判斷boolean的值

 @Test
public void testAssertTrueFalse() {
assertTrue(1 == 1);
    assertFalse(1 == 2);
}

assertNull,assertNotNull

就不多說了

assertSame, assertNotSame

判斷兩者對象引用是否相同

assertThat

這個是重點,可以傳入一個hamcrest提供的Matcher接口來進行判斷

Assert.assertThat(obj, Matchers.xxx);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM