zoukankan      html  css  js  c++  java
  • 强大的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;
    import org.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;
    import com.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

    http://www.open-open.com/lib/view/open1359969858611.html

  • 相关阅读:
    批量新增百万条数据 十百万条数据
    sqlserver 组内排序
    EF ++属性会更新实体
    Entity Framework Core: A second operation started on this context before a previous operation completed
    abp Cannot access a disposed object. A common cause of this error is disposing
    abp xunit Can not register IHostingEnvironment. It should be a non-abstract class. If not, it should be registered before.”
    hangfire enqueued but not processing(hangfire 定时任务入队列但不执行)
    EF 更新实体 The instance of entity type 'BabyEvent' cannot be tracked because another instance
    datatable to entiy list 不支持可空类型和枚举类型
    webapi 设置不显示接口到swaggerUI
  • 原文地址:https://www.cnblogs.com/softidea/p/4159133.html
Copyright © 2011-2022 走看看