java每日Demo之junit5单元测试

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


前言

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

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

验证和断言

验证:是校验验证的对象是否发生过某些行为,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对象打桩

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


	}

@Mock注解

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

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

@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("测试结束执行的方法");
	}

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

}

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

写一个测试静态方法的类

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对象一起使用在同一个线程的话就会把报错。

案列

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为在Spring Boot中进行JUnit5单元测试,你要在测试类上使用@SpringBootTest注解。这个注解会加载整个Spring应用程序上下文,以便你可以使用Spring的功能和特性。一个简单的示例是这样的: ```java @SpringBootTest class MyUnitTest { // 测试方法 @Test void myTest() { // 测试逻辑 } } ``` 在测试方法中,你可以使用@Autowired注解来注入依赖的bean,并使用@Transactional注解标记方法以支持事务管理。@Transactional注解可以确保在测试完成后自动回滚,以保持测试的独立性。 与JUnit4相比,JUnit5是Spring Boot 2.2.0版本及以上的默认单元测试库。因此,如果你使用的是最新版本的Spring Boot,你应该使用JUnit5编写你的单元测试。 在系统环境方面,你要确保你的Java版本是8及以上,Maven版本是3.3及以上,以及使用IDEA作为开发工具。当你创建一个Maven项目时,你要导入spring-boot-starter-test依赖来使用单元测试的场景。如果你使用的是Spring Initializr创建的项目,它将自动引入单元测试的依赖,你不要手动添加。 这是使用JUnit5进行Spring Boot单元测试的一般步骤。希望对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [JUnit5单元测试(基于SpringBoot)](https://blog.csdn.net/maogenb/article/details/124459093)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值