本文将介绍Mockito库的入门以下注释:@Mock、@Spy、入门@Captor和@InjectMocks。入门
第一个选项是入门用MockitoJUnitRunner注释JUnit测试:
@ExtendWith(MockitoExtension.class)public class MockitoAnnotationUnitTest { ...}
或者,我们可以通过调用
MockitoAnnotations.openMocks()以编程方式启用Mockito注释:
@BeforeEachpublic void init() { MockitoAnnotations.openMocks(this);}
Mockito中使用最广泛的入门注释是@Mock。我们可以使用@Mock创建和注入模拟实例,入门而无需手动调用Mockito.Mock。入门
在以下示例中,我们将在不使用@Mock注释的情况下手动创建一个模拟的ArrayList:
@Testpublic void whenNotUseMockAnnotation_thenCorrect() { List mockList = Mockito.mock(ArrayList.class); mockList.add("one"); Mockito.verify(mockList).add("one"); assertEquals(0, mockList.size()); Mockito.when(mockList.size()).thenReturn(100); assertEquals(100, mockList.size());}
或者使用@mock注释注入mock:
@MockList<String> mockedList;@Testpublic void whenUseMockAnnotation_thenMockIsInjected() { mockedList.add("one"); Mockito.verify(mockedList).add("one"); assertEquals(0, mockedList.size()); Mockito.when(mockedList.size()).thenReturn(100); assertEquals(100, mockedList.size());}
现在让我们看看如何使用@Spy注解来监视现有实例。
在以下示例中,在不使用@spy注释的情况下创建受监视列表:
@Testpublic void whenNotUseSpyAnnotation_thenCorrect() { List<String> spyList = Mockito.spy(new ArrayList<String>()); spyList.add("one"); spyList.add("two"); Mockito.verify(spyList).add("one"); Mockito.verify(spyList).add("two"); assertEquals(2, spyList.size()); Mockito.doReturn(100).when(spyList).size(); assertEquals(100, spyList.size());}
使用@spy注释:
@SpyList<String> spiedList = new ArrayList<String>();@Testpublic void whenUseSpyAnnotation_thenSpyIsInjectedCorrectly() { spiedList.add("one"); spiedList.add("two"); Mockito.verify(spiedList).add("one"); Mockito.verify(spiedList).add("two"); assertEquals(2, spiedList.size()); Mockito.doReturn(100).when(spiedList).size(); assertEquals(100, spiedList.size());}
接下来,我们来看看如何使用@Captor注解来创建ArgumentCaptor实例。
在以下示例中,我们将在不使用@Captor注释的情况下创建ArgumentCaptor:
@Testpublic void whenNotUseCaptorAnnotation_thenCorrect() { 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());}
使用@Captor来创建一个ArgumentCaptor实例:
@MockList mockedList;@Captor ArgumentCaptor argCaptor;@Testpublic void whenUseCaptorAnnotation_thenTheSame() { mockedList.add("one"); Mockito.verify(mockedList).add(argCaptor.capture()); assertEquals("one", argCaptor.getValue());}
现在,让我们讨论如何使用@InjectMocks注解将mock字段自动注入到测试对象中。
在以下示例中,我们将使用@InjectMocks将mock wordMap注入MyDictionary dic:
@MockMap<String, String> wordMap;@InjectMocksMyDictionary dic = new MyDictionary();@Testpublic void whenUseInjectMocksAnnotation_thenCorrect() { Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning"); assertEquals("aMeaning", dic.getMeaning("aWord"));}
类MyDictionary:
public class MyDictionary { Map<String, String> wordMap; public MyDictionary() { wordMap = new HashMap<String, String>(); } public void add(final String word, final String meaning) { wordMap.put(word, meaning); } public String getMeaning(final String word) { return wordMap.get(word); }}
我们可能想向Spy注入一个mock:
@MockMap<String, String> wordMap;@SpyMyDictionary spyDic = new MyDictionary();
然而,Mockito不支持向Spy中注入mock,以下测试导致异常:
@Test public void whenUseInjectMocksAnnotation_thenCorrect() { Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning"); assertEquals("aMeaning", spyDic.getMeaning("aWord")); }
如果我们想将mock与spy一起使用,我们可以通过构造函数手动注入mock:
MyDictionary(Map<String, String> wordMap) { this.wordMap = wordMap;}
我们现在可以手动创建Spy,而不是使用注解:
@MockMap<String, String> wordMap; MyDictionary spyDic;@BeforeEachpublic void init() { MockitoAnnotations.openMocks(this); spyDic = Mockito.spy(new MyDictionary(wordMap));}
现在测试将通过。
通常,当我们试图实际使用@Mock或@Spy注解的实例时,我们可能会遇到NullPointerException:
public class MockitoAnnotationsUninitializedUnitTest { @Mock List<String> mockedList; @Test(expected = NullPointerException.class) public void whenMockitoAnnotationsUninitialized_thenNPEThrown() { Mockito.when(mockedList.size()).thenReturn(1); }}
大多数情况下,发生这种情况只是因为我们忘记启用Mockito注解。
因此,想要使用Mockito注解时,我们都必须采取额外的步骤进行初始化。
Mockito的注解最大限度地减少了重复的mock创建代码,使测试更具可读性。
@InjectMock对于注入@Spy和@Mock实例都是必要的。
责任编辑:武晓燕 来源: 今日头条 Mockito注解@Mock(责任编辑:知识)
桂发祥(002820.SZ)2020年度净利润降70.41% 基本每股收益0.12元
英特尔下代至强Granite Rapids实物曝光 面积针脚猛增
英伟达正在准备新Hopper H100计算卡 带来更多显存版本
嘉里物流(00636.HK)因购股权获行使发行8万股 每股发行价10.2港元
英特尔下代至强Granite Rapids实物曝光 面积针脚猛增