JUnit - The first sight
JUnit是一個Java語言的單元測試框架,目前主流為JUnit4 與JUnit5
junit5功能多又比較全面,因為junit5有向下相容junit4所以常常會看到混著寫的情況
可以觀察annotation, method的package,以下則是junit 5
org.junit.jupiter.api.
若是以下的則是junit 4
org.junit.
由於mocking的物件會橫跨至其他class,因此為了做mock session延展至在unit test階段,可以initMocks
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
Getting start with @Mock, @Spy, @Captor and @InjectMocks
以上都是Mockito的annotation
不同的annotations 使用方式來啟動mockito test
- MoclitoJUnitRunner 就是最基本的JUnit測試
@RunWith(MockitoJUnitRunner.class)
public class MockitoAnnotationTest {
...
}
- MockitoAnnotations.initMocks() 以programming的方式透過它來啟動Mockito
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
- MockitoJUnit.rule() (比較少看到...)
public class MockitoInitWithMockitoJUnitRuleUnitTest {
@Rule
public MockitoRule initRule = MockitoJUnit.rule();
...
}
@Mock Annotation
最常見到到的Annotation, 用@Mock 建立/注入mocked instances
在沒有annotation的時候則需要自己寫Mockito instance
List mockList = Mockito.mock(ArrayList.class);
vs
@Mock
List<String> mockedList;
@Spy annotation 相較於Mock是產生假的實例,spy就是去監視存在的instance
List<String> spyList = Mockito.spy(new ArrayList<String>());
vs
@Spy
List<String> spiedList = new ArrayList<String>();
所以能夠用真實的method來操作instance,也能用Stubbed method去模擬回傳情境
@Captor Annotation 產生參數捕獲器 ArgumentCaptor instance
攔截讓mock的物件執行method的參數
List mockList = Mockito.mock(List.class);
ArgumentCaptor<String> arg = ArgumentCaptor.forClass(String.class);
List mockList = Mockito.mock(List.class);
ArgumentCaptor<String> arg = ArgumentCaptor.forClass(String.class);
mockList.add("one");
Mockito.verify(mockList).add(arg.capture());
assertEquals("one", arg.getValue());
vs
@Mock
List mockedList;
@Captor
ArgumentCaptor argCaptor;
mockedList.add("one");
Mockito.verify(mockedList).add(argCaptor.capture());
assertEquals("one", argCaptor.getValue());
@InjectMocks Annotation 自動注入模擬資料,也就是能將@InhjectMocks的物件去注入 @Mock的模擬資料(這也說明為什麼你不能把Autowired的物件丟進去了
@Mock
Map<String, String> wordMap;
@InjectMocks
MyDictionary dic = new MyDictionary();
@Test
public void whenUseInjectMocksAnnotation_thenCorrect() {
Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");
assertEquals("aMeaning", dic.getMeaning("aWord"));
Mockito Annotation又是來減少code量,並且易讀性高。
要注入@Spy 跟 @Mock, @InjectMocks 是必須要有的
@Mock 與 @MockBean 不同?
運用 Mockito.mock 建立一個物件並設定在call method或verify後回傳特定值
在class上用junit runner annotation
@RunWith(MockitoJUnitRunner.class)
Spring Boot's @MockBean annotation 是mock Spring application context. (Application context是Spring的應用程式)
也就可以做到模擬在call method或verify後回傳的值
在class上用spring runner annotation
@RunWith(SpringRunner.class)
References:
留言
張貼留言