【mockito】單元測試之mockito簡單使用


背景

項目使用的是springmvc+mybatis 開發;

mock包為 mockito-all;雖然也引用了powermock,但截至目前,還未使用到;如果使用到后續再補相關筆記。

 

mock,個人理解,有兩個場景比較常見吧。一個是在項目初期接口定義好后沒有實現邏輯階段;另一個就是針對已經有的邏輯自測階段,而又不想(或者依賴的別人接口不想關心)被別人所左右的情況。

不管那種情況,都是一個目的:降低別人對自己的干擾。

 

大概從兩個方面記錄單測的mock:

dapper層:

  dapper層,目前是給mybatis的定義接口層;這一層主要會結合mybatis.xml 與數據庫進行交互;當開發階段沒有寫完邏輯時,那就需要先來個“假實現”,這樣不會影響團隊中其他小伙伴的工作開展嘛。

public class ReportMediaDayMapperTest {

    @Mock
    private ReportMediaDayMapper reportMediaDayMapper; // 定義了mybatis與數據庫交互時,用到的接口

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @After
    public void tearDown() throws Exception {

    }

    @Test
    public void getAdvertiserAndMediaStatList() throws Exception {
        MediaSearchModel searchModel = new MediaSearchModel();
        List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
        when(reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list); // mock一個場景,就是當請求getAdvertiserAndMediaStatList方法時,返回值為指定的 list;
    List<AdvertiserAndMediaStatViewModel> list2 = reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel); 
    assertTrue(list2.isEmpty()); // 斷言list2為空,因為上面就是一個實例化並沒有賦值,所以也是為空了。
}

 

對於DAO層,主要用到的是 @Mock的使用。那么這個注解的作用究竟是什么呢?下面會結合另外一個一起總結。

 

service層:

  主要mock對象一般就是對DAO層的依賴,另外就是別人的Service實現類;

@RunWith(MockitoJUnitRunner.class)
public class MediaServiceImplTest {

    @Mock
    private ReportMediaDayMapper mediaDayMapper; // mock 一個DAO層的接口

    @InjectMocks
    private MediaServiceImpl mediaService; // Mock一個Service的實現類,為什么用@InjectMocks,一會兒說

    @Test
    public void getAdvertiserAndMediaStatList() throws Exception {
        MediaSearchModel searchModel = new MediaSearchModel();
        List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
        when(mediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list);

        list = mediaService.getAdvertiserAndMediaStatList(searchModel);

        assertTrue(list.isEmpty());
    }

 

其實,對於以上兩個場景的mock,主要是圍繞着@Mock、@InjectMocks進行玩的。那么他們分別代表什么意思呢?

官方文檔上是這么描述的:

  • mock()/@Mock: create mockspy()/@Spy: partial mocking, real methods are invoked but still can be verified and stubbed
  • @InjectMocks: automatically inject mocks/spies fields annotated with @Spy or @Mock -- 這句話理解意思是它會把上下文中你標記為@Spy和@Mock的對象都自動注解進去。是不是就相當於把實現類中的私有成員屬性(比如ReportMediaDayMapper的依賴)給偷梁換柱了
  • verify(): to check methods were called with given arguments
    • can use flexible argument matching, for example any expression via the any()
    • or capture what arguments where called using @Captor instead

另外,就是你可能會注意到了@RunWith(MockitoJUnitRunner.class),其實也可以用另外一種方式(看↓)處理,就是初始化一些需要的東西。

@Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this); 
    }

    @After
    public void tearDown() throws Exception {

    }

 

至此,簡單的mock測試就完了。其實只是冰山一角。mockito中有很多很多很多。常用的一些@spy、@mock、@injectMocks、以及Verify、when then、doreturn ……

 

參考:

https://github.com/hehonghui/mockito-doc-zh

http://site.mockito.org/

http://static.javadoc.io/org.mockito/mockito-core/2.7.6/org/mockito/Mockito.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM