Java|spring Mock入门

本文介绍了Java中Mockito库的使用,包括为何使用Mockito进行模拟测试、其工作原理,以及如何在不同场景下应用,如模拟RPC服务。通过实例展示了验证行为、Stubbing、参数匹配等功能,并提供了Spring环境下使用Mockito的示例。

背景Java中目前主要的Mock测试工具有Mockito,JMock,EasyMock等等,很多Java Mock库如EasyMockJMock都是expect-run-verify(期望-运行-测试)的方式,而Mockito则更简单:在执行后的互动中提问。使用Mockito主要记住,在执行前stub,而后在交互中验证即可

  mock测试:就是在测试过程中,对于某些不容易构造或者 不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。这个虚拟的对象就是mock对象。mock对象就是真实对象在调试期间的代替品。

Requirements(需求)

No Dependency:每一个团队都希望自己开发的模块不依赖任何其它的外界条件,沟通成本仅限于双方接口定义。

Why(为什么要使用它?)

敏捷、轻量级

避免开发模块之间的耦合

简单 极为灵活

Principle

通过定义基于方法的模拟调用规则模拟任何代码的调用过程替代真实代码执行!

How(如何使用?)

场景

模拟RPC服务:目前存在很多应用通过RPC服务调用获取数据,应用前端的展现严重依赖后端服务的稳定性,在测试阶段可以选择通过模拟的方式直接模拟后端服务。

一、在项目中使用Maven引用mock

1)普通工程

http://www.cnblogs.com/lyy-2016/p/6155445.html

<dependency> 

    <groupId>org.mockito</groupId> 

    <artifactId>mockito-all</artifactId> 

    <version>1.8.5</version> 

<scope>test</scope> 

</dependency>

<dependency>

    <groupId>org.mockito</groupId>

    <artifactId>mockito-core</artifactId>

    <version>2.7.13</version>

</dependen

 

2)spring 工程,尤其是spring web

http://blog.csdn.net/lee272616/article/details/52760447

1.  <dependency>  

2.    <groupId>org.springframework</groupId>  

3.    <artifactId>spring-test</artifactId>  

4.  </dependency> 

 

二、例子

1)http://www.tuicool.com/articles/J7BFr2A

 

(1)验证行为

 import static org.mockito.Mockito.*;

 //mock creation

 List mockedList = mock(List.class);

 //using mock object

 mockedList.add("one");

 mockedList.clear();

 //verification

 verify(mockedList).add("one");

 verify(mockedList).clear();

一旦创建 mock 将会记得所有的交互。你可以选择验证你感兴趣的任何交互

 

还能验证交互行为次数,如下面例子:

mockedList.add("once");

mockedList.add("twice");

mockedList.add("twice");

mockedList.add("three times");

mockedList.add("three times");

mockedList.add("three times");

//following two verifications work exactly the same - times(1) is used by default

verify(mockedList).add("once");

verify(mockedList, times(1)).add("once");

//exact number of invocations verification

verify(mockedList, times(2)).add("twice");

verify(mockedList, times(3)).add("three times");

//verification using never(). never() is an alias to times(0)verify(mockedList, never()).add("never happened");

//verification using atLeast()/atMost()

verify(mockedList, atLeastOnce()).add("three times");

verify(mockedList, atLeast(2)).add("five times");

verify(mockedList, atMost(5)).add("three times");

 

 

(2)Stubbing

//You can mock concrete classes, not just interfaces

 LinkedList mockedList = mock(LinkedList.class);

 

 //stubbing

 when(mockedList.get(0)).thenReturn("first");

 when(mockedList.get(1)).thenThrow(new RuntimeException());

 

 //following prints "first"

 System.out.println(mockedList.get(0));

 

 //following throws runtime exception

 System.out.println(mockedList.get(1));

 

 //following prints "null" because get(999) was not stubbed

 System.out.println(mockedList.get(999));

 

(3)迭代器stubbing,例子

when(mock.someMethod("some arg"))

 .thenThrow(new RuntimeException())

 .thenReturn("foo")

 

when(mock.someMethod("some arg"))

 .thenThrow(new RuntimeException())

 .thenReturn("foo")

(4)Spy

(5)doReturn()|doThrow()|doAnswer()|doNothing()|doCallRealMethod()

 

3)参数匹配

参数匹配器允许灵活的验证或stubbing

 //stubbing using built-in anyInt() argument matcher

 when(mockedList.get(anyInt())).thenReturn("element");

 

 //stubbing using custom matcher (let's say isValid() returns your own matcher implementation):

 when(mockedList.contains(argThat(isValid()))).thenReturn("element");

 

 //following prints "element"

 System.out.println(mockedList.get(999));

 

 //you can also verify using an argument matcher

 verify(mockedList).get(anyInt());

Note:创建mock,使用@Mock注解

public class ArticleManagerTest {

 @Mock private ArticleCalculator calculator;

 @Mock private ArticleDatabase database;

 @Mock private UserProvider userProvider;

 

 private ArticleManager manager;

在基础类或者测试 runner 里面:

MockitoAnnotations.initMocks(testClass);

例子如下:

   public class ArticleManagerTest extends SampleBaseTestCase {

       @Mock private ArticleCalculator calculator;

       @Mock(name = "database") private ArticleDatabase dbMock

       @Spy private UserProvider userProvider = new ConsumerUserProvider();

       @InjectMocks private ArticleManager manager;

       @Test public void shouldDoSomething() {

           manager.initiateArticle();

          verify(database).addListener(any(ArticleListener.class));

       }

   }

   public class SampleBaseTestCase {

       @Before public void initMocks() {

           MockitoAnnotations.initMocks(this);

       }

2)   }利用springmock类进行单元测试

MockHttpServletRequest request= newMockHttpServletRequest("POST","/index.do");   
    request.addParameter("username","name");   
    request.addParameter("password","word"); 


Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi.SimpleNamingContextBuilder.class org.springframework.mock.web.DelegatingServletInputStream.class org.springframework.mock.web.DelegatingServletOutputStream.class org.springframework.mock.web.HeaderValueHolder.class org.springframework.mock.web.MockExpressionEvaluator.class org.springframework.mock.web.MockFilterChain.class org.springframework.mock.web.MockFilterConfig.class org.springframework.mock.web.MockHttpServletRequest.class org.springframework.mock.web.MockHttpServletResponse.class org.springframework.mock.web.MockHttpSession.class org.springframework.mock.web.MockMultipartFile.class org.springframework.mock.web.MockMultipartHttpServletRequest.class org.springframework.mock.web.MockPageContext.class org.springframework.mock.web.MockRequestDispatcher.class org.springframework.mock.web.MockServletConfig.class org.springframework.mock.web.MockServletContext.class org.springframework.mock.web.PassThroughFilterChain.class org.springframework.mock.web.portlet.MockActionRequest.class org.springframework.mock.web.portlet.MockActionResponse.class org.springframework.mock.web.portlet.MockMultipartActionRequest.class org.springframework.mock.web.portlet.MockPortalContext.class org.springframework.mock.web.portlet.MockPortletConfig.class org.springframework.mock.web.portlet.MockPortletContext.class org.springframework.mock.web.portlet.MockPortletPreferences.class org.springframework.mock.web.portlet.MockPortletRequest.class org.springframework.mock.web.portlet.MockPortletRequestDispatcher.class org.springframework.mock.web.portlet.MockPortletResponse.class org.springframework.mock.web.portlet.MockPortletSession.class org.springframework.mock.web.portlet.MockPortletURL.class org.springframework.mock.web.portlet.MockRenderRequest.class org.springframework.mock.web.portlet.MockRenderResponse.class org.springframework.test.AbstractDependencyInjectionSpringContextTests.class org.springframework.test.AbstractSingleSpringContextTests.class org.springframework.test.AbstractSpringContextTests.class org.springframework.test.AbstractTransactionalDataSourceSpringContextTests.class org.springframework.test.AbstractTransactionalSpringContextTests.class org.springframework.test.AssertThrows.class org.springframework.test.ConditionalTestCase.class org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests.class org.springframework.test.annotation.DirtiesContext.class org.springframework.test.annotation.ExpectedException.class org.springframework.test.annotation.IfProfileValue.class org.springframework.test.annotation.NotTransactional.class org.springframework.test.annotation.ProfileValueSource.class org.springframework.test.annotation.Repeat.class org.springframework.test.annotation.SystemProfileValueSource.class org.springframework.test.annotation.Timed.class org.springframework.test.jpa.AbstractAspectjJpaTests.class org.springframework.test.jpa.AbstractJpaTests.class org.springframework.test.jpa.OrmXmlOverridingShadowingClassLoader.class org.springframework.test.web.AbstractModelAndViewTests.class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值