当前位置:   article > 正文

java每日Demo之junit5单元测试_根据编码规范的作业,对自己所写的代码,用junit编写5个单元测试用例,需使用startsw

根据编码规范的作业,对自己所写的代码,用junit编写5个单元测试用例,需使用startsw

提示:内容纯属实战运用,不玩虚的。看明白就可以用在工作中,现学现用。


前言

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

提示:以下是本篇文章正文内容,下面案例可供参考

一、为什么要使用mock(Mockito)?

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();
	}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

执行结果:
在这里插入图片描述

验证和断言

验证:是校验验证的对象是否发生过某些行为,Mockit中验证的方法是:verify(),对mock出来的对象的行为进行验证
代码示例:

	// 下面是校验该random对象是否已经执行了2次,如果没有就会报错
		Mockito.verify(random,Mockito.times(2)).nextInt();
  • 1
  • 2

断言:断言使用的类是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());
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

给Mock对象打桩

打桩的意思就是给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));


	}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

@Mock注解

该注解是代替Random random = Mockito.mock(Random.class);用的,以后就不需要这么写了就直接,需要注意的是写这个注解之后必须要加MockitoAnnotations.openMocks(this);这行代码,不然会报错

//代替Random random = Mockito.mock(Random.class);写法
    @Mock
	private Random random;
  • 1
  • 2
  • 3

@BeforeEach与@BeforeAfter注解

@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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

spy方法与@Spy注解

spy()方法与mock()方法不同的是:

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));
		
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

mock静态方法

直接上代码,先写两个静态方法:

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";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

写一个测试静态方法的类

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());
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

运行结果:

在这里插入图片描述
在这里插入图片描述
需要注意的是:
MockedStatic demo = Mockito.mockStatic(StaticUtils.class);这个mock出来的对象使用完要关闭,否则两个mock对象一起使用在同一个线程的话就会把报错。

案列

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/274052
推荐阅读
相关标签
  

闽ICP备14008679号