成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Mockito、Mock、Spy、Captor和InjectMocks入門

開發 前端
大多數情況下,發生這種情況只是因為我們忘記啟用Mockito注解。因此,想要使用Mockito注解時,我們都必須采取額外的步驟進行初始化。

概述

本文將介紹Mockito庫的以下注釋:@Mock、@Spy、@Captor和@InjectMocks。

啟用Mockito注釋

  • MockitoJUnitRunner

第一個選項是用MockitoJUnitRunner注釋JUnit測試:

@ExtendWith(MockitoExtension.class)
public class MockitoAnnotationUnitTest {
    ...
}
  • MockitoAnnotations.openMocks()

或者,我們可以通過調用
MockitoAnnotations.openMocks()以編程方式啟用Mockito注釋:

@BeforeEach
public void init() {
    MockitoAnnotations.openMocks(this);
}

@Mock

Mockito中使用最廣泛的注釋是@Mock。我們可以使用@Mock創建和注入模擬實例,而無需手動調用Mockito.Mock。

在以下示例中,我們將在不使用@Mock注釋的情況下手動創建一個模擬的ArrayList:

@Test
public 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:

@Mock
List<String> mockedList;

@Test
public 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注解來監視現有實例。

在以下示例中,在不使用@spy注釋的情況下創建受監視列表:

@Test
public 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注釋:

@Spy
List<String> spiedList = new ArrayList<String>();

@Test
public 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

接下來,我們來看看如何使用@Captor注解來創建ArgumentCaptor實例。

在以下示例中,我們將在不使用@Captor注釋的情況下創建ArgumentCaptor:

@Test
public 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實例:

@Mock
List mockedList;

@Captor 
ArgumentCaptor argCaptor;

@Test
public void whenUseCaptorAnnotation_thenTheSame() {
    mockedList.add("one");
    Mockito.verify(mockedList).add(argCaptor.capture());

    assertEquals("one", argCaptor.getValue());
}

@InjectMocks

現在,讓我們討論如何使用@InjectMocks注解將mock字段自動注入到測試對象中。

在以下示例中,我們將使用@InjectMocks將mock wordMap注入MyDictionary dic:

@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"));
}

類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

我們可能想向Spy注入一個mock:

@Mock
Map<String, String> wordMap;

@Spy
MyDictionary 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,而不是使用注解:

@Mock
Map<String, String> wordMap; 

MyDictionary spyDic;

@BeforeEach
public void init() {
    MockitoAnnotations.openMocks(this);
    spyDic = Mockito.spy(new MyDictionary(wordMap));
}

現在測試將通過。

使用注解時遇到NPE

通常,當我們試圖實際使用@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實例都是必要的。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2021-06-08 07:32:01

框架Mock測試

2011-03-31 09:22:20

PowerMock

2023-04-11 08:02:26

單測技術JUnit框架

2023-07-30 22:29:51

BDDMockitoAssert測試

2011-04-13 11:38:09

Mockito

2017-03-23 16:02:10

Mock技術單元測試

2024-07-29 12:12:59

2023-10-07 08:45:47

2016-10-20 12:34:08

android單元測試java

2022-10-17 00:14:55

微服務稅mock代理服務

2023-10-13 18:02:57

JUnitMockito關系

2019-03-01 09:55:28

HTTPMock架構

2012-04-19 09:37:12

ibmdw

2015-07-03 10:41:47

ReactWebpack

2022-01-28 14:39:59

Swaggerpostmanmock

2023-11-01 15:32:58

2023-08-01 07:27:42

Mockito測試Callback

2010-03-01 10:24:20

Oracle RAC

2011-05-31 14:22:23

2020-07-23 07:24:40

Kubernetes大數據開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲成人一区二区三区 | 先锋资源网站 | 中文字幕亚洲一区 | 久久久久久久一区 | 草草视频在线观看 | 三级成人在线 | 免费黄色大片 | 国精日本亚洲欧州国产中文久久 | 中文字幕日韩一区 | 神马久久av | 欧美日韩精品中文字幕 | 亚洲国产精品99久久久久久久久 | 亚洲精品久久久 | 自拍偷拍亚洲欧美 | 日韩精品 电影一区 亚洲 | 欧美日韩精品中文字幕 | 日本精品一区二区三区在线观看视频 | 成人福利在线观看 | 黄色在线免费观看 | 日本手机看片 | 欧美成人免费在线视频 | 久久毛片 | 97精品超碰一区二区三区 | 亚洲精品三级 | 少妇特黄a一区二区三区88av | 综合久久av| 免费成人高清在线视频 | 国产午夜精品理论片a大结局 | jlzzjlzz国产精品久久 | 国产午夜精品视频 | 欧美 日韩精品 | 一区二区三区亚洲视频 | 成人不卡在线 | 国产乱码高清区二区三区在线 | 精品欧美一区二区三区久久久 | 亚洲精品久久久久久宅男 | 国产伦一区二区三区四区 | 成人欧美日韩一区二区三区 | 国产清纯白嫩初高生视频在线观看 | 天天草天天| 久久国产精品久久久久久 |