強大的Mockito測試框架

1自動生成Mock類

在需要Mock的屬性上標記@Mock註解,然後@RunWith中配置Mockito的TestRunner或者在setUp()方法中顯示調用MockitoAnnotations.initMocks(this);生成Mock類即可。

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

只要在被測試類上標記@InjectMocks,Mockito就會自動將標記@Mock、@Spy等註解的屬性值注入到被測試類中。

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類替換。

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

因爲@Mock針對接口生成Mock類,所以我們是沒法調用到真實的實現類的方法。可以使用@Spy註解標註屬性,並且標註@Resource註解讓Spring注入真實實現類,那麼Mockito就會自動生成Spy類。

例如:

@InjectMocks

@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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章