mockito的用法
well,说来惭愧,之前一直知道有这么个东西,但总是看不进去。刚好趁着这次迭代间隙有些闲暇,认真看了下,大概明白是怎么回事了。
首先,mock是个概念,这个词的本意就是“虚假的”、“模仿的”。在测试的时候,很多情况下都无法获取真正的对象,如Servlet对象,但测试又需要这个对象,怎么办?
当然是弄个假的给糊弄一下啦。
其次,mock的实现有很多,本文只关心Mockito,其他的请自行百度哈。
看到所有的资料都说Mockito有两方面的作用:1. 验证方法调用; 2. 指定特定条件下某个方法的返回值,或者执行特定的动作。
废话少说,直接上代码验证一下。
1. 先上pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>win.larryzeal</groupId> <artifactId>mockito-study</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!--2.x not good 呵呵--> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
2. 再提供一个接口 Processor,不提供实现。
package win.larryzeal.mockito.study; public interface Processor { void process(); int get(); void cb(int a, int b, Callback cb); } package win.larryzeal.mockito.study; public interface Callback { int onSuccess(); int onFail(); }
3. 然后看一下怎么验证调用 - 需要特别指出的是,mock的对象相当于加了一层代理,可以认为是实现。如下:
package win.larryzeal.mockito.study; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; //1. 验证方法调用 public class MockTest { @Test public void r1() { Processor mock = Mockito.mock(Processor.class); mock.process(); //注意,这里相当于验证之前的调用! Mockito .verify(mock) //Alias to verify(mock, times(1)) 验证是否调用一次 .process(); } @Test public void r2() { Processor mock = Mockito.mock(Processor.class); mock.process(); //注意,这里相当于验证之前的调用! Mockito .verify(mock, Mockito.times(3)) //Alias to verify(mock, times(1)) 验证是否调用n次 .process(); } }
上面的验证很简单,就是验证指定mock的特定方法的调用 - 可以是调用次数,也可以是超时等,还可以是复合的验证条件,如Mockito.timeout(1000).times(3)。
4. 再来看看怎么定制特定方法的返回结果 - 很有用噢,特别是针对远程调用、接口调用等情况。
package win.larryzeal.mockito.study; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; //2. 指定某个方法的返回值 public class MockTest { @Test public void r3() { Processor mock = Mockito.mock(Processor.class); //注意,这里相当于设定mock里某个方法的返回值!在测试遇到嵌套方法,且嵌套方法不便于调用时,非常有用。 Mockito .when(mock.get()) .thenReturn(0xff); //这里是可变参数,多次调用的情况下,依次返回相应的数值;如果超出次数,返回最后一个值。 System.out.println(mock.get()); } }
嗯嗯,when用于指定调用的方法,thenXxx用于指定返回结果 或者 抛出异常。
5. 再来看看回调的情况 - 传入的参数是条件,根据条件来调用特定的回调。
package win.larryzeal.mockito.study; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; //2. 指定某个方法的返回值,或者是执行特定的动作 public class MockTest { @Test public void r4() { Processor mock = Mockito.mock(Processor.class); //这里,是设定在特定条件下调用特定的回调! - 这个特定的条件是不同的参数,可以是具体的,也可以是Mockito.anyXxx。 Mockito .doAnswer((InvocationOnMock invocation) -> { Callback cb = invocation.getArgumentAt(2, Callback.class); cb.onFail(); return null; //嗯?这里的返回值是? }) .when(mock) .cb(Mockito.eq(1), Mockito.eq(-1), Mockito.any(Callback.class)); //TODO 如果用matcher,那所有的参数都需要是matcher //实际的调用 mock.cb(1, -1, new Callback() { @Override public int onSuccess() { System.out.println("ok"); return 200; } @Override public int onFail() { System.out.println("fail"); return 500; } }); mock.cb(1, 1, null); } }
前面设定条件,然后实际调用下,就是这么简单!
ps:暂时不明白那个Invocation的返回值是干嘛用的,稍后再说。
6. 最后看看 spy,Mockito 除了mock()方法,还提供了spy,简单的说就是可以不指定方法的返回值,而是返回类型的默认值(零值)。如下:
package win.larryzeal.mockito.study; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class MockTest { @Test public void r5() { //spy,除非设定,返回返回默认值 Processor spy = Mockito.spy(Processor.class); //多次调用的情况下,依次返回相应的数值;如果超出次数,返回最后一个值。 //Mockito.when(spy.get()).thenReturn(3, 5, 9); //不指定的情况,返回0 System.out.println(spy.get()); System.out.println(spy.get()); System.out.println(spy.get()); System.out.println(spy.get()); //同样可以校验执行次数 // Mockito.verify(spy).get(); //一次 Mockito.verify(spy, Mockito.times(4)).get(); } }
ok,至此基本就算大功告成了,赶快去试试吧?
posted on 2019-05-24 00:40 LarryZeal 阅读(2633) 评论(0) 编辑 收藏 举报