在spring中使用Mockito測試框架

1自動生成Mock類

在須要Mock的屬性上標記@Mock註解,而後@RunWith(MockitoJUnitRunner.class)或者在setUp()方法中顯示調用MockitoAnnotations.initMocks(this);生成Mock類便可。 html

 

2自動注入Mock類到被測試類

只要在被測試類上標記@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

 

3 Mock方法定製不再用錄製、播放了

Mockito的Mock方法定製可讀性很強,並且也不須要像EasyMock那樣錄製播放,定製後就可使用。 dom

例如: ide

when(userDao.selectAll()). svn

                   thenReturn(Collections.<UserDomain>emptyList()); 測試

4有些方法想Mock定製,有些想調用真實方法

由於@Mock針對接口生成Mock類,因此咱們是無法調用到真實的實現類的方法。可使用@Spy註解標註屬性,而且標註@Resource註解讓Spring注入真實實現類,那麼Mockito就會自動生成Spy類。 this

 

例如: google

@InjectMocks spa

@Resource(name =」userService」)

privateUserService userService;

        

@Spy

@Resource

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

相關文章
相關標籤/搜索