Mockito單元測試-註解的詳細使用
阿新 • • 發佈:2019-02-04
1,@Mock
@Target(FIELD)
@Retention(RUNTIME)
@Documented
public@interfaceMock{
Answers answer()defaultAnswers.RETURNS_DEFAULTS;
String name()default"";
Class<?>[] extraInterfaces()default{};
}
@Mock註解,我們用來初始化Mock物件。代替我們在不使用註解的場景中使用的Mockito.mock(xxx.class)方法。
2,@Spy
@Retention(RUNTIME)
@Target(FIELD
@Documented
public@interfaceSpy{}
@Spy註解,具體的使用我們可以參考文件
*<h4>Important gotcha on spying real objects!</h4>
*<ol>
*<li>Sometimes it's impossible or impractical to use {@linkMockito#when(Object)}for stubbing spies.
*Thereforefor spies it is recommended to always use <code>
* family of methods for stubbing.Example:
*
*<pre class="code"><code class="java">
*List list =newLinkedList();
*List spy = spy(list);
*
*//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
* when(spy.get(0)).thenReturn("foo");
*
*//You have to use doReturn() for stubbing
* doReturn("foo").when(spy).get(0);
*</code></pre>
*</li>
*
*<li>Mockito<b>*does not*</b> delegate calls to the passed real instance, instead it actually creates a copy of it.
*Soif you keep the real instance and interact with it, don't expect the spied to be aware of those interaction
* and their effect on real instance state.
*The corollary is that when an <b>*unstubbed*</b> method is called <b>*on the spy*</b> but <b>*not on the real instance*</b>,
* you won't see any effects on the real instance.</li>
*
*<li>Watch out forfinal methods.
*Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + you try to stub a final method = trouble.
*Also you won't be able to verify those method as well.
*</li>
*</ol>
*
*<p>
*<strong>One last warning :</strong>if you call <code>MockitoAnnotations.initMocks(this)</code> in a
*superclass<strong>constructor</strong> then this will not work.It is because fields
* in subclass are only instantiated after superclass constructor has returned.
*It's better to use @Before.
*<strong>Instead</strong> you can also put initMocks() in your JUnit runner (@RunWith) or use the built-in
*{@link org.mockito.runners.MockitoJUnitRunner}.
3,@InjectMocks
Mockito通過此註解會自動注入mocks 物件到我們註解的變數中。如果注入失敗,不會通知我們,所以我們需要自己對失敗的物件做處理。
4,MockitoAnnotations.initMocks
初始化我們的Mock註解。
5,例項
package com.raycloud.dmj.services.gray;
import com.raycloud.cache.CacheException;
import com.raycloud.cache.ICache;
import com.raycloud.dmj.domain.Configurable;
import com.raycloud.grayrelease.HitReceipt;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.mockito.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* GrayServiceTest
* Created by jinglongjun on 16/3/4.
*/
publicclassGrayServiceTestextendsTestCase{
@Spy
@InjectMocks
privateGrayService grayService;
@Mock
Configurable config;
@Mock
ICache cache;
@Before
publicvoid setUp(){
MockitoAnnotations.initMocks(this);
}
@Test
publicvoid testList(){
List<String> strs =newArrayList<String>();
strs.add("1");
strs.add("2");
System.out.println(strs);
}
/**
* 正常碰撞進入快取
*
* @throws CacheException
*/
@Test
publicvoid testSetCacheList()throwsCacheException{
HitReceipt hitReceipt =newHitReceipt();
hitReceipt.setUid("1");
hitReceipt.setNick("1");
hitReceipt.setForward(true);
Map<String,HitReceipt> users =newHashMap<String,HitReceipt>();
Mockito.when(cache.get(GrayUtil.getCacheUsers())).thenReturn(users);
grayService.setCacheList(hitReceipt);
grayService.setCacheList(hitReceipt);
grayService.setCacheList(hitReceipt);
grayService.setCacheList(hitReceipt);
Mockito.verify(cache,Mockito.atLeastOnce()).set(GrayUtil.getCacheUsers(), users);
}