关于测试组件junit切换testng的示例以及切换方式分享

这篇具有很好参考价值的文章主要介绍了关于测试组件junit切换testng的示例以及切换方式分享。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概要

本文作者之前写单元测试都是使用junit
场景有以下三种场景
仅junit
spring+junit
mock+spring+junit

本文会用第三种场景写简单的实例列出junit和testng的代码相关说明
并会将涉及的修改点一一说明
目的帮助大家了解testng及具体的切换方式

首先看看junit和testng的区别

JUnit和TestNG是两种流行的Java测试框架,用于测试Java应用程序中的代码。它们具有以下区别:

  1. 组织方式:JUnit使用Annotations来标注测试方法,而TestNG使用XML文件来组织测试。

  2. 支持的测试类型:JUnit 4支持单元测试,而TestNG支持功能测试、集成测试和端到端测试。

  3. 并发测试:TestNG支持并发测试,可以在同一时间运行多个测试用例,而JUnit不支持并发测试。

  4. 数据提供者:TestNG支持数据提供者,可以在不同参数上运行相同的测试用例,而JUnit不支持数据提供者。

  5. 测试套件:TestNG支持测试套件,可以组织不同的测试用例,而JUnit不支持测试套件。

  6. 依赖测试:TestNG支持依赖测试,可以在一组测试之前运行必需的测试,而JUnit不支持依赖测试。

实践篇

摸拟业务逻辑代码

场景,有三层以上代码层次的业务场景,需要摸拟最底层数据层代码

简单对象
package com.riso.junit;

/**
 * DemoEntity
 * @author jie01.zhu
 * date 2023/10/29
 */
public class DemoEntity implements java.io.Serializable {


	private long id;
	private String name;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "DemoEntity{" + "id=" + id + ", name='" + name + '\'' + '}';
	}


}

数据层摸拟类
package com.riso.junit;

import org.springframework.stereotype.Component;

/**
 * DemoDaoImpl
 * @author jie01.zhu
 * date 2023/10/29
 */
@Component
public class DemoDaoImpl {
	public int insert(DemoEntity demoEntity) {
		System.out.println("dao.insert:" + demoEntity.toString());
		return 1;
	}
}

业务逻辑层摸拟类
package com.riso.junit;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * DemoServiceImpl
 * @author jie01.zhu
 * date 2023/10/29
 */
@Service
public class DemoServiceImpl {

	@Resource
	DemoDaoImpl demoDao;

	public int insert(DemoEntity demoEntity) {
		System.out.println("service.insert:" + demoEntity.toString());
		return demoDao.insert(demoEntity);
	}

}

后台任务摸拟类
package com.riso.junit;

import org.springframework.stereotype.Component;

/**
 * DemoTaskImpl
 * @author jie01.zhu
 * date 2023/10/29
 */
@Component
public class DemoTaskImpl {
	DemoServiceImpl demoService;

	public int insert(DemoEntity demoEntity) {
		System.out.println("task.insert:" + demoEntity.toString());
		return demoService.insert(demoEntity);
	}
}

基于spring+mock+junit

maven依赖

   <!-- test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.12.4</version>
            <scope>test</scope>
        </dependency>
package com.riso.junit.test;

import com.riso.junit.DemoDaoImpl;
import com.riso.junit.DemoEntity;
import com.riso.junit.DemoServiceImpl;
import com.riso.junit.DemoTaskImpl;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

/**
 *  junit test
 * @author jie01.zhu
 * date 2023/10/29
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}, inheritLocations = true)
public class Test1 {

	/**
	 * 测试入口类
	 */
	@Resource
	@InjectMocks
	DemoTaskImpl demoTask;

	/**
	 * mock的类的中间传递类
	 */
	@Resource
	@InjectMocks
	DemoServiceImpl demoService;

	/**
	 * 被mock的类
	 */
	@Mock
	DemoDaoImpl demoDao;

	@Test
	public void test1() {
		// 初始化mock环境
		MockitoAnnotations.openMocks(this);

		DemoEntity demoEntity = new DemoEntity();
		demoEntity.setId(1L);
		demoEntity.setName("name1");

		Mockito.doReturn(0).when(demoDao).insert(Mockito.any());
		int result = demoTask.insert(demoEntity);
		Assert.assertEquals(result, 0);

	}
}

基于spring+mock+testng

有二个测试类,测试参数不同,主要体现在单元测试外,控制二个测试类,按并发场景做简单的集成测试

maven依赖

        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.14.3</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.4.13</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.12.4</version>
            <scope>test</scope>
        </dependency>
package com.riso.testng.test;

import com.riso.testng.ContextConfig;
import com.riso.testng.DemoDaoImpl;
import com.riso.testng.DemoEntity;
import com.riso.testng.DemoTaskImpl;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.Test;

import javax.annotation.Resource;

/**
 *  junit test
 * @author jie01.zhu
 * date 2023/10/29
 */
@SpringBootTest(classes = {ContextConfig.class})
public class Test1 extends AbstractTestNGSpringContextTests {

	/**
	 * 测试入口类
	 */
	@Resource
	DemoTaskImpl demoTask;

	/**
	 * 被mock的类 选用spy方式  默认使用原生逻辑,仅mock的方法才被mock
	 */
	@SpyBean
	@Resource
	DemoDaoImpl demoDao;

	@Test
	public void test1() {

		DemoEntity demoEntity = new DemoEntity();
		demoEntity.setId(1L);
		demoEntity.setName("name1");

		Mockito.doReturn(0).when(demoDao).insert(Mockito.any());
		int result = demoTask.insert(demoEntity);
		Assert.assertEquals(result, 0);

	}
}

package com.riso.testng.test;

import com.riso.testng.ContextConfig;
import com.riso.testng.DemoDaoImpl;
import com.riso.testng.DemoEntity;
import com.riso.testng.DemoTaskImpl;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.Test;

import javax.annotation.Resource;

/**
 *  junit test
 * @author jie01.zhu
 * date 2023/10/29
 */
@SpringBootTest(classes = {ContextConfig.class})
public class Test2 extends AbstractTestNGSpringContextTests {

	/**
	 * 测试入口类
	 */
	@Resource
	DemoTaskImpl demoTask;

	/**
	 * 被mock的类 选用spy方式  默认使用原生逻辑,仅mock的方法才被mock
	 */
	@SpyBean
	@Resource
	DemoDaoImpl demoDao;


	@Test
	public void test2() {
		
		DemoEntity demoEntity = new DemoEntity();
		demoEntity.setId(2L);
		demoEntity.setName("name2");

		Mockito.doReturn(2).when(demoDao).insert(Mockito.any());
		int result = demoTask.insert(demoEntity);
		Assert.assertEquals(result, 2);

	}
}

testNg的 配置文件,也是执行入口

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="test" parallel="tests" thread-count="2">
    <test name="test1" group-by-instances="true">
        <classes>
            <class name="com.riso.testng.test.Test1"/>
        </classes>
    </test>
    <test name="test2" group-by-instances="true">
        <classes>
            <class name="com.riso.testng.test.Test2"></class>
        </classes>
    </test>
</suite>

运行方式如下:
关于测试组件junit切换testng的示例以及切换方式分享,junit,集成测试,spring boot,maven

示例的差异点

junit与testng的主要变动不大,有以下几个点需要注意
注解部分

junit此处注解
@RunWith(SpringJUnit4ClassRunner.class)
testng不再使用此注解
需要继承 org.springframework.test.context.testng.AbstractTestNGSpringContextTests

在before,after中

testng完全兼容,但会多出Suite ,它代替xml配置中,单元测试类之上的生命周期

testng多出按配置执行功能

首先testng的单元测试可以与junit一样,单独运行
在这个基础上,也能通过testng xml按配置运行,可以见上面的例子

附上关于mock 新旧写法改进

以前要摸拟调用对象的跨二层以上类时,需要通过InjectMocks 做为中间传递,才能成功mock掉二层以上的类
换成spyBean后,不需要再使用InjectMocks ,会自动从注入中找到
这个小插曲也是我自己对以前mock的修正,一并附上

小结

通过以上说明,及示例
testng是完全兼容junit的,且改动很小
注解,断言都是直接兼容的(只需要更换导入的包路径既可)

当然,我不是为了使用而使用,一切都要建立上有需求的基础上
junit对我来讲,已经满足不了我的需求,
为了能够编写集成测试,同时复用已有的单元测试,我选择了testng
希望以上分享,能够对读者有用.

朱杰
2023-10-29文章来源地址https://www.toymoban.com/news/detail-734231.html

到了这里,关于关于测试组件junit切换testng的示例以及切换方式分享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Tab切换以及倒计时组件封装

    功能 支持默认选中tab 子元素可以是文本或者图片 自定义tab的数量,并自适应展示 实现方式 用ul li标签遍历传入的tabs数组参数渲染 判断是否传入背景,未传则显示文字 绑定点击事件 特点 简单易用 可适配性 功能 常用于榜单或者活动结束倒计时、或者开始倒计时、从而提高

    2024年02月09日
    浏览(43)
  • springboot项目使用Junit5 + mockito + jacoco 实现单元测试以及代码覆盖率检查

    在创建springboot项目时会默认添加spring-boot-starter-test依赖,其中已经包含了junit、mockito依赖,根据springboot版本的不同junit和mockito的版本也会有所不同 先说一下各自功能: junit只说一点,junt4和junit5的注解不同,使用方式略有差异,其他不赘述了,基本用法都懂。 mockito是mock的

    2023年04月23日
    浏览(58)
  • 【react从入门到精通】React父子组件通信方式详解(有示例)

    【分享几个国内免费可用的ChatGPT镜像】 【10几个类ChatGPT国内AI大模型】 【用《文心一言》1分钟写一篇博客简直yyds】 【用讯飞星火大模型1分钟写一个精美的PPT】 在上一篇文章《JSX详解》中我们了解了什么是jsx以及jsx的语法规则。 本文中我们将详细了解React父子组件通信方式

    2024年02月05日
    浏览(98)
  • Testng数据驱动之DataProvider的使用方式

    @DataProvider 注解帮助我们编写数据驱动的测试用例。@DataProvider 注解使我们能够通过传递不同的数据集多次运行测试方法。 以下是@DataProvider 注解支持的属性列表: 属性 描述 name 此数据提供者的名称。如果未提供,则此数据提供程序的名称将自动设置为方法的名称。带注解的

    2024年02月03日
    浏览(41)
  • 【记录】LangChain|Ollama结合LangChain使用的速通版(包含代码以及切换各种模型的方式)

    官方教程非常长,我看了很认可,但是看完了之后呢就需要一些整理得当的笔记让我自己能更快地找到需求。所以有了这篇文章。【写给自己看的,里面半句废话的解释都没有,如果看不懂的话直接看官方教程再看我的】 我是不打算一开始就用OpenAI的,打算先用一下开源模型

    2024年04月14日
    浏览(37)
  • 如何在TestNG中忽略测试用例

    在这篇文章中,我们将讨论如何在TestNG中忽略测试用例。TestNG帮助我们忽略使用@Test注释的情况,我们可以在不同的级别上忽略这些情况。 首先,只忽略一个测试方法或测试用例。 第二,忽略一个类及其子类中的所有情况。 第三个是,忽略包及其子包中的所有情况。 下面我

    2024年04月27日
    浏览(30)
  • 从零开发短视频电商 单元测试(TestNG)

    官网 : https://testng.org/doc/index.html TestNG是一个基于 Java 的开源测试框架。该框架受到 JUnit 和 NUnit 的启发,但引入了一些新功能,使其更强大且更易于使用。您可以在测试实施期间创建 HTML 报告。它具有分组测试、注释、参数化等功能,有助于更快地创建测试。 TestNG的核心特

    2024年02月15日
    浏览(39)
  • Java的单元测试Testng和mock

    目录 单元测试重要性 TestNG TestNG官网介绍 TestNG教程 TestNG注解: 

    2024年02月07日
    浏览(38)
  • 接口测试-关于postman的几种参数请求方式

    (1)POST的数据类型 对于post请求方式,一般都是要对请求发送相应的一些参数的,而参数的注入一般填写在Body中。  如上图所示,在Body中,有多种类型选择: none:一般都不使用 form-data:  对于form-data,是采用键值对的方式进行存储,即将该表单的数据组织成Key-Value形式,

    2024年02月12日
    浏览(84)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包