在須要Mock的屬性上標記@Mock註解,而後@RunWith(MockitoJUnitRunner.class)或者在setUp()方法中顯示調用MockitoAnnotations.initMocks(this);生成Mock類便可。 html
只要在被測試類上標記@InjectMocks,Mockito就會自動將標記@Mock、@Spy等註解的屬性值注入到被測試類中。 java
import static org.mockito.Mockito.when; import java.util.Collections; import java.util.List; import javax.annotation.Resource; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; importorg.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.cdai.ssi.user.dao.UserDao; import com.cdai.ssi.user.domain.UserDomain; import com.cdai.ssi.user.dto.UserDto; importcom.cdai.ssi.user.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring/spring-config.xml"}) public class UserServiceTest { @InjectMocks @Resource(name= "userService") privateUserService userService; @Mock privateUserDao userDao; @Before publicvoid setUp() { MockitoAnnotations.initMocks(this); } @Test publicvoid testQueryAll() { when(userDao.selectAll()). thenReturn(Collections.<UserDomain>emptyList()); List<UserDto>dtoList = userService.queryAll(); Assert.assertTrue(dtoList.isEmpty()); } }
@InjectMocks的問題是:若是被測試類是代理類,那麼注入會失效。好比上面的UserService若是是事務或者其餘AOP代理類,那麼進入@Test方法時UserService中的DAO屬性不會被Mock類替換。 spring
Mockito的Mock方法定製可讀性很強,並且也不須要像EasyMock那樣錄製播放,定製後就可使用。 dom
例如: ide
when(userDao.selectAll()). svn
thenReturn(Collections.<UserDomain>emptyList()); 測試
由於@Mock針對接口生成Mock類,因此咱們是無法調用到真實的實現類的方法。可使用@Spy註解標註屬性,而且標註@Resource註解讓Spring注入真實實現類,那麼Mockito就會自動生成Spy類。 this
例如: google
@InjectMocks spa
@Resource(name =」userService」)
privateUserService userService;
privateUserDao userDao;
Spy類就能夠知足咱們的要求。若是一個方法定製了返回值或者異常,那麼就會按照定製的方式被調用執行;若是一個方法沒被定製,那麼調用的就是真實類的方法。
若是咱們定製了一個方法A後,再下一個測試方法中又想調用真實方法,那麼只需在方法A被調用前,調用Mockito.reset(spyObject);就好了。
import static org.mockito.Mockito.when; import org.mockito.Mockito; public class TestMockObject implementsITestMock { publicstatic void main(String[] args) { ITestMockmock = Mockito.mock(TestMockObject.class); System.out.println(mock.test1()); System.out.println(mock.test2()); ITestMockspy = Mockito.spy(new TestMockObject()); System.out.println(spy.test1()); System.out.println(spy.test2()); when(spy.test1()).thenReturn(100); System.out.println(spy.test1()); Mockito.reset(spy); System.out.println(spy.test1()); System.out.println(spy.test2()); when(spy.test1()).thenReturn(104); System.out.println(spy.test1()); } @Override publicint test1() { System.out.print("RealTest1()!!! - "); return1; } @Override publicint test2() { System.out.print("RealTest2()!!! - "); return2; } }
輸出爲:
0
0
Real Test1()!!! – 1
Real Test2()!!! – 2
Real Test1()!!! – 100
Real Test1()!!! – 1
Real Test2()!!! – 2
Real Test1()!!! – 104
要注意的是,對Spy對象的方法定製有時須要用另外一種方法:
===============================================================================
Importantgotcha on spying real objects!
Sometimes it’s impossible to usewhen(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throwsIndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn(「foo」);
//You have to use doReturn() for stubbing
doReturn(「foo」).when(spy).get(0);
===============================================================================
由於用when(spy.f1())會致使f1()方法被真正執行,因此就須要另外一種寫法。
Mockito文檔
http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html