單元測試

單元測試在開發的過程當中可能會被不少的人所忽略,其實也不是真的被忽略多是因爲巨大的業務壓力而致使沒有時間去寫那些測試,而是直接經過集成測試完沒問題就提交給測試進行測試後上線了。這樣其實不少時候反而會浪費大量的時間在測試上面,而適量的寫好單元測試有如下一些優點:spring

  • 有單元測試可能會提升整個集成測試的進度並且最重要的是作到對本身寫的代碼知根知底,更有底氣的推到線上去。
  • 在對邏輯進行重構的時候能夠直接經過單元測試能把控整個重構的邏輯不發生重大誤差,給後來者造福了。

服務單元測試

下面是一段獲取緩存邏輯的單元測試。CacheManager中封裝了邏輯從緩衝中取數據,若是數據沒有取到則從repositoryCache.loadStoreByKey(key)中load數據。spring-mvc

public void getValueIfNullLoadTest() {
    /* 從repository裏面取數據 */
    RepositoryCache repositoryCache = mock(RepositoryCache.class);
    String key = anyString();
    when(repositoryCache.loadStoreByKey(key)).thenReturn("test");
    when(repositoryCache.getCacheName()).thenReturn(Constants.CACHE);

    CacheManager.addRepository(repositoryCache);
    String value = CacheManager.getValueIfNullLoad(Constants.CACHE, key, String.class);

    Assert.assertTrue(StringUtils.equals(value, "test"));

    /* 從緩存中取 */
    value = CacheManager.getValueByCache(Constants.CACHE, key, String.class);
    Assert.assertTrue(StringUtils.equals(value, "test"));

}
  • mockrepositoryCache,當調用repositoryCacheloadStoreByKey或者getCacheName方法後返回測試數據。
  • 後面執行CacheManager.getValueIfNullLoad中正常的業務邏輯。
  • 最後判斷結果是否符合預期。

controller單元測試

上面一小節只是針對普通的服務單元進行測試,可是遇到http的接口測試就無能爲力了,下面來介紹下若是寫http接口的單元測試。緩存

public class UserControllerUnitTest {

    private MockMvc mockMvc;

    @Mock
    private UserService userService;

    @InjectMocks
    private UserController userController;

    @Before
    public void init(){
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders
                .standaloneSetup(userController)
                .addFilters(new CORSFilter())
                .build();
    }

    @Test
    public void test_get_all_success() throws Exception {
        List<User> users = Arrays.asList(
                new User(1, "Daenerys Targaryen"),
                new User(2, "John Snow"));
        when(userService.getAll()).thenReturn(users);
        mockMvc.perform(MockMvcRequestBuilders.get("/users"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
                .andExpect(mvcResult -> {
                    String responseStr = mvcResult.getResponse().getContentAsString();
                    //針對結果進行驗證。
                });
        Mockito.verify(userService, times(1)).getAll();
        Mockito.verifyNoMoreInteractions(userService);
    }

}
  • mock一個服務userService
  • InjectMocks userController後經過MockitoAnnotations.initMocks(this)userService這個mock的服務注入到userController中。
  • MockMvcBuilders.standaloneSetup(userController).build(); 建立MockMvc
  • 後面就是模擬發送http請求,而後驗證response的操做和上一節的相似。
  • 最後是驗證mock服務的接口調用次數。

總結

可能你也會在項目中看到不少的單元測試,可是隨着項目的迭代那些單元測試已經失效,又或者是你會看到在進行單元測試的時候會去啓動整個項目容器去作運行,不過只要有就是好的,後面在進行項目迭代的過程當中別忘了把unit test寫上吧。mvc

參考

Unit Test Spring MVC Rest Service: MockMVC, JUnit, Mockito單元測試

相關文章
相關標籤/搜索