這篇要探討在實作Testing上,我們的會員管理系統是利用Spring Boot,因此就是直接導入Spring Boot Test
下列出Login部分的Unit Test
package com.poyu.practice.unit.service;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import com.poyu.mms.MemberManagerSystemApplication;
import com.poyu.mms.dao.ITbUserRepository;
import com.poyu.mms.entity.po.TbUser;
import com.poyu.mms.entity.vo.UserVo;
import com.poyu.mms.service.ILoginService;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MemberManagerSystemApplication.class)
public class LoginServiceTest {
@Autowired
private ILoginService loginService;
@MockBean
private ITbUserRepository userRepository;
@Before
public void setup() {
}
@Test
public void login() throws Exception {
TbUser user = new TbUser("tester", "1234");
when(userRepository.findByAccount("tester")).thenReturn(Optional.of(user));
UserVo userVo = new UserVo();
userVo.setAccount("tester");
userVo.setPwd("1234");
// 正確帳號密碼
assertEquals(user, loginService.login(userVo).get());
// 錯誤帳號密碼
userVo.setPwd("4321");
assertEquals(null, loginService.login(userVo));
}
}
裡面有關Spring的Annotation部分我就不多說了,關注在Mock上,Mock是一種Test Double
先介紹兩個術語:
我們在做測試的時候,SUT就是我們要測試的程式,但常常會有對應到的元件會相依,也就是DOC,例如上方單元測試的程式碼,我們要測試登入我們系統的Service是否正確,登入的Service就是我們的SUT,而UserRepository就是我們的相依物件DOC,主要負責撈取DB的資料
那我們在針對Service做單元測試的時候,其實並不需要確認DB連線與資料的部分,因此我們可以將UserRepository回傳的內容固定,就是利用Test Double概念,如此一來就可以很單一單純的測試service的部分了
由此可知,Test Double測試替身,就是將相依的物件替身化,不會有效能、錯誤等等的其他因素影響本體,讓SUT可以更簡單更單純的測試
圖片來源:XUnit Test Patterns
圖片來源:XUnit Test Patterns
參考資料、延伸閱讀:
下集預告:實作分享 - Docker