赞
踩
提示:内容纯属实战运用,不玩虚的。看明白就可以用在工作中,现学现用。
Mockito脑图:
junit5单元测试前先引入以下依赖
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
</dependency>
提示:以下是本篇文章正文内容,下面案例可供参考
Mock可以理解为创建一个虚假的对象,或者模拟出一个对象,在测试环境中用来替换掉真实的对象,以达到我们可以:
1.验证该对象的某些方法的调用情况,调用了多少次
2.给这个对象的行为做一个定义,来指定返回结果或者指定待定的动作
Mock方法来自org.mockito.Mock,它表示可以mock一个对象或者是接口。
代码示列:
@Test
void add(){
Random random = Mockito.mock(Random.class);
System.out.println(random.nextInt());
//下面这行代码就是用Mockito来校验mock出来的random对象的nextInt()方法执行的次数,
// 下面是校验该random对象是否已经执行了2次,如果没有就会报错
Mockito.verify(random,Mockito.times(2)).nextInt();
}
执行结果:
验证:是校验验证的对象是否发生过某些行为,Mockit中验证的方法是:verify(),对mock出来的对象的行为进行验证
代码示例:
// 下面是校验该random对象是否已经执行了2次,如果没有就会报错
Mockito.verify(random,Mockito.times(2)).nextInt();
断言:断言使用的类是Assertions.
代码示例:
@Test
void addAssertion(){
Random random = Mockito.mock(Random.class);
//给random.nextInt()打桩为100。和赋值差不多一个意思
Mockito.when(random.nextInt()).thenReturn(100);
//校验mock出来的random对象执行方法nextInt()之后的值是否为100,否的话就报错
Assertions.assertEquals(100,random.nextInt());
}
打桩的意思就是给mock对象规定一定的行为,使其按照我们的要求来执行具体的操作。一般用来测试具体的逻辑方法的时候,如果正常返回就规定返回一个特定值,没有返回特定值的时候就抛异常,一些实例代码是行为规定(打桩)经常要用到的方法。在开发单元测试中经常用到。
代码示例;
@Test void testAdd() { //下面这行代码也可以用注解的方式来代替,然后要写MockitoAnnotations.openMocks(this);方法不然会报错 //Random mock = Mockito.mock(Random.class); //mock的打桩 Mockito.when(random.nextInt()).thenReturn(100); //如果走完add()方法返回结果是3,那么就给这个行为赋值(打桩)为100 Mockito.when(demoServiceImplTest.add(1, 2)).thenReturn(100); //如果走完add()方法返回结果是3,那么就给行为赋值(打桩)为抛出一个运行时异常,这个一般是测可能会有抛出异常的方法,我们会制造抛出异常的结果,在这个demoServiceImplTest.add(1, 2)行为正好返回的结果符合我们定义的异常结果的话就会打桩(给行为定义)抛出异常。 Mockito.when(demoServiceImplTest.add(1, 2)).thenThrow(new RuntimeException()); //走真实的add方法,不会直接欺骗赋值,在for循环中可能用到,第一次循环走打桩出来的值,第二次循环走真实的方法 Mockito.when(demoServiceImplTest.add(1, 2)).thenCallRealMethod(); //assertEquals(0, demoUnderTest.add(1, 2)); }
该注解是代替Random random = Mockito.mock(Random.class);用的,以后就不需要这么写了就直接,需要注意的是写这个注解之后必须要加MockitoAnnotations.openMocks(this);这行代码,不然会报错
//代替Random random = Mockito.mock(Random.class);写法
@Mock
private Random random;
@BeforeEach注解就是在执行测试方法之前执行的方法,@BeforeAfter自然就是在测试方法执行完之后执行
@Spy private demoServiceImpl demoServiceImplTest; @Mock private Random random; @BeforeEach void setUp() { //测试之前执行的方法 MockitoAnnotations.openMocks(this); demoServiceImplTest = new demoServiceImpl(); } @AfterEach void after() { System.out.println("测试结束执行的方法"); }
1.被spy的对象会走真实的方法,而mock对象不会(mock的行为和返回的结果都是我们赋予的,就是我们自己模拟出来的。spy的话就会走真实方法的行为和返回结果)
2,spy()方法的参数是对象实例,mock的参数是class
代码示列:
public class demoServiceImpl { public int add(int a,int b){ return a+b; } @Spy private demoServiceImpl demoServiceImplTest; @Mock private Random random; @BeforeEach void setUp() { //测试之前执行的方法 //如果是用@Mock,那么下面这行代码就需要写 MockitoAnnotations.openMocks(this); demoServiceImplTest = new demoServiceImpl(); } @Test void setDemoServiceImplTest(){ //走真实的add()方法,并且返回3,不会像mock方法一样还要给打桩然后返回打桩之后的行为方法值 Assertions.assertEquals(3,demoServiceImplTest.add(1,2)); } }
直接上代码,先写两个静态方法:
public class StaticUtils {
private StaticUtils(){
}
//返回指定区间的 Integer List
public static List<Integer> range(int start,int end){
return IntStream.range(start,end).boxed().collect(Collectors.toList());
}
//返回En字符串
public static String name(){
return "En";
}
}
写一个测试静态方法的类
public class StaticUtilsTest { @Test void range(){ MockedStatic<StaticUtils> demo = Mockito.mockStatic(StaticUtils.class); //给这个静态方法一个2到6的范围数值,然后打桩如果在这个范围的话就打桩成10,11,12这个list集合 demo.when(()->StaticUtils.range(2,6)).thenReturn(Arrays.asList(10,11,12)); //以下方法断言之后就会报错 Assertions.assertTrue(StaticUtils.range(2,6).contains(15)); } @Test void name(){ MockedStatic<StaticUtils> demo = Mockito.mockStatic(StaticUtils.class); demo.when(StaticUtils::name).thenReturn("AK"); //期望返回AK,然后上个方法已经打桩成AK了,所以运行的时候不会报错 Assertions.assertEquals("AK",StaticUtils.name()); } }
运行结果:
需要注意的是:
MockedStatic demo = Mockito.mockStatic(StaticUtils.class);这个mock出来的对象使用完要关闭,否则两个mock对象一起使用在同一个线程的话就会把报错。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。