在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

相关文章
相关标签/搜索