当前位置: 首页 > news >正文

杭州企业网站建设公司南宁整合推广公司

杭州企业网站建设公司,南宁整合推广公司,wordpress 2017,山东省建设工程管理局网站为鼓励单元测试,特分门别类示例各种组件的测试代码并进行解说,供开发人员参考。 本文中的测试均基于JUnit5。 单元测试实战(一)Controller 的测试 单元测试实战(二)Service 的测试 单元测试实战&am…

为鼓励单元测试,特分门别类示例各种组件的测试代码并进行解说,供开发人员参考。

本文中的测试均基于JUnit5。

单元测试实战(一)Controller 的测试

单元测试实战(二)Service 的测试    

单元测试实战(三)JPA 的测试

单元测试实战(四)MyBatis-Plus 的测试

单元测试实战(五)普通类的测试

单元测试实战(六)其它

我们常用的DAO层开发框架包括JPA(Spring Boot Data Jpa)和MyBatis-Plus。

框架都提供根据一定规约自动生成查询/更新的操作,如代理接口。这一部分责任在框架本身,我们不需测试。因此DAO的测试应主要针对自定义查询/更新操作。

JPA的测试注解是@DataJpaTest,Mybatis-Plus的是@MyBatisPlusTest;它们的思想是一致的,此次先讲JPA。

概述

JPA组件表现为Repository对象。如果是Spring Data JPA标准的Repository,且使用接口代理,那么理论上是不需要测试的;但实际中不排除想验证订制代码(native SQL、JPQL、标准查询API,以及胶水代码)的需求。

JPA测试有专门的@DataJpaTest注解,是Spring boot测试框架提供的功能,因此它是有Spring上下文的,使用JUnit的SpringExtension扩展类。

测试还是遵循经典三段式:given、when、then;即:假设xxx……那么当yyy时……应该会zzz。

在每个测试之前应清理/重置测试数据,即操作的数据实体。

断言应主要检查数据存取行为是否符合预期。

依赖

JPA测试除了依赖JUnit和Spring boot测试框架外还依赖一个内存数据库,我们用H2,如下:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>test</scope>
</dependency>

示例

以下是用代理接口实现的UserRepository:

package com.aaa.api.auth.repository;import org.springframework.data.jpa.repository.JpaRepository;
import com.aaa.api.auth.entity.User;
import org.springframework.stereotype.Repository;import java.util.List;
import java.util.Optional;@Repository
public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findByUserCode(String userCode);List<User> findTop10ByNameContaining(String keyword);
}

上面的Repository虽然没有订制代码,但不妨碍我们用它来演示Repository测试的写法。

以下是对UserRepository进行测试的测试类:

package com.aaa.api.auth.repository;import com.aaa.api.auth.entity.User;
import jakarta.persistence.Query;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.TestPropertySource;import java.util.List;import static org.assertj.core.api.Assertions.assertThat;@DataJpaTest
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(properties = {//"spring.datasource.driver-class-name=org.h2.Driver",//"spring.datasource.url=jdbc:h2:mem:api_auth_test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL;DATABASE_TO_LOWER=TRUE;NON_KEYWORDS=user",//"spring.datasource.username=sa","spring.jpa.hibernate.ddl-auto=create-drop","spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop","spring.jpa.properties.hibernate.globally_quoted_identifiers=true"
})
class UserRepositoryTest {@Autowiredprivate UserRepository repo;@Autowiredprivate TestEntityManager entityManager;private final User u1 = new User();private final User u2 = new User();private final User u3 = new User();@BeforeEachvoid setUp() {u1.setName("张三");u1.setUserCode("zhangsan");u1.setRole(User.ADMIN);u1.setEmail("zhangsan@aaa.net.cn");u1.setMobile("13600001234");u2.setName("李四");u2.setUserCode("lisi");u2.setRole(User.ADMIN);u2.setEmail("lisi@aaa.net.cn");u2.setMobile("13800001234");u3.setName("王五");u3.setUserCode("wangwu");u3.setRole(User.USER);u3.setEmail("wangwu@aaa.net.cn");u3.setMobile("13900001234");}@Testvoid testSave() {Query q = entityManager.getEntityManager().createQuery("from User");repo.save(u1);assertThat(q.getResultList()).hasSize(1);repo.save(u2);assertThat(q.getResultList()).hasSize(2);User u = repo.save(u3);assertThat(q.getResultList()).hasSize(3);u3.setRole(User.ADMIN);repo.save(u3);assertThat(q.getResultList()).hasSize(3);assertThat(entityManager.find(User.class, u.getId()).getRole()).isEqualTo(User.ADMIN);}      @Testvoid testFindAll() {entityManager.persist(u1);entityManager.persist(u2);entityManager.persist(u3);List<User> entities = repo.findAll();assertThat(entities).size().isEqualTo(3);assertThat(entities.get(0).getId()).isNotNull();assertThat(entities.get(1).getId()).isNotNull();assertThat(entities.get(2).getId()).isNotNull();}@Testvoid testFindByUserCode() {entityManager.persist(u1);entityManager.persist(u2);entityManager.persist(u3);User u1 = repo.findByUserCode("zhangsan").orElse(null);assertThat(u1).isNotNull();assertThat(u1.getRole()).isEqualTo(User.ADMIN);User u2 = repo.findByUserCode("lisi").orElse(null);assertThat(u2).isNotNull();assertThat(u2.getRole()).isEqualTo(User.ADMIN);User u3 = repo.findByUserCode("wangwu").orElse(null);assertThat(u3).isNotNull();assertThat(u3.getRole()).isEqualTo(User.USER);u3.setRole(User.ADMIN);entityManager.persist(u3);u3 = repo.findByUserCode("wangwu").orElse(null);assertThat(u3).isNotNull();assertThat(u3.getRole()).isEqualTo(User.ADMIN);}@Testvoid testFindTop10ByNameContaining() {entityManager.persist(u2);entityManager.persist(u3);List<User> users = repo.findTop10ByNameContaining("张三");assertThat(users).isEmpty();users = repo.findTop10ByNameContaining("李四");assertThat(users).hasSize(1);users = repo.findTop10ByNameContaining("五");assertThat(users).hasSize(1);}}

测试类说明:

第16行,标注本测试为@DataJpaTest。

18-25行是数据源和JPA属性的订制。

@DataJpaTest、@WebMvcTest以及@SpringBootTest等测试其实是需要Spring Boot的Configuration的;因此我们在测试目录里可能(尤其在多模块工程里)有个专用于测试的Mock Application,注解为@SpringBootApplication(空类,不需要main方法),并且在src/test/resources下还可以有application.properties(或yaml)。而更灵活的方式是使用第18行的@TestPropertySource的properties属性。

@DataJpaTest这个注解会在测试时自动将数据源替换为内存数据库H2的;如果不想要这种替换,或者要订制其url等属性,那么就可以将第17行、第19-21行的注释放开。

第24行的spring.jpa.properties.hibernate.globally_quoted_identifiers=true可以避免数据库保留字与表名/列名冲突。

第29行,我们将待测试类对象作为测试类的一个属性,并使用@Autowired进行注入。

第32行,我们注入了一个TestEntityManager;它作为一个实用工具,帮我们在测试中插数据、查数据,这样就避免了直接使用repo的方法插数据、查数据,因为这些方法本身就是待测目标。

第34-36行提供了三个测试数据,并在setUp()方法中进行初始化/重置。@BeforeEach注解使得setUp()方法在每个测试之前都会执行一遍。

从59行开始,是测试方法。该测试类中,没有任何Mock对象,因此也就不存在given - when - then三段式结构。测试方法都是直接对测试数据进行CRUD操作并检查操作结果,代码都是自解释的。

总结

对于JPA Repository的测试,推荐使用@DataJpaTest注解。

如需订制内存数据库(datasource)的属性,则令@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE),然后在@TestPropertySource.properties里写订制属性。

Repository应设计为单纯的对数据实体的CRUD操作,因此通常不需Mock任何依赖对象。


文章转载自:
http://anachronous.dtrz.cn
http://gilly.dtrz.cn
http://microsporophyll.dtrz.cn
http://avitaminosis.dtrz.cn
http://ejaculator.dtrz.cn
http://dumbbell.dtrz.cn
http://arrogancy.dtrz.cn
http://iodophor.dtrz.cn
http://democracy.dtrz.cn
http://pelvimetry.dtrz.cn
http://illutation.dtrz.cn
http://chemist.dtrz.cn
http://straw.dtrz.cn
http://growthmanship.dtrz.cn
http://vanadic.dtrz.cn
http://chlorpicrin.dtrz.cn
http://deflagration.dtrz.cn
http://helvetia.dtrz.cn
http://towkay.dtrz.cn
http://booth.dtrz.cn
http://urinoir.dtrz.cn
http://fugacity.dtrz.cn
http://listing.dtrz.cn
http://fascinatress.dtrz.cn
http://prelingual.dtrz.cn
http://appraiser.dtrz.cn
http://forte.dtrz.cn
http://rayleigh.dtrz.cn
http://proctoclysis.dtrz.cn
http://afterwar.dtrz.cn
http://krimmer.dtrz.cn
http://burying.dtrz.cn
http://dither.dtrz.cn
http://turdine.dtrz.cn
http://vinelet.dtrz.cn
http://anionic.dtrz.cn
http://iblis.dtrz.cn
http://data.dtrz.cn
http://homosphere.dtrz.cn
http://foy.dtrz.cn
http://peavey.dtrz.cn
http://intracutaneous.dtrz.cn
http://flightiness.dtrz.cn
http://superphysical.dtrz.cn
http://orchitis.dtrz.cn
http://dex.dtrz.cn
http://preterite.dtrz.cn
http://micrococcic.dtrz.cn
http://chaffing.dtrz.cn
http://diabetogenic.dtrz.cn
http://blacktop.dtrz.cn
http://cloistress.dtrz.cn
http://skunk.dtrz.cn
http://vection.dtrz.cn
http://inexpungible.dtrz.cn
http://sulphadiazine.dtrz.cn
http://circumrotation.dtrz.cn
http://unorthodox.dtrz.cn
http://intently.dtrz.cn
http://minestrone.dtrz.cn
http://crepitation.dtrz.cn
http://beg.dtrz.cn
http://endothecium.dtrz.cn
http://sniffle.dtrz.cn
http://approximation.dtrz.cn
http://airflow.dtrz.cn
http://hostility.dtrz.cn
http://rebec.dtrz.cn
http://beauty.dtrz.cn
http://enginery.dtrz.cn
http://skite.dtrz.cn
http://brevirostrate.dtrz.cn
http://ebulliency.dtrz.cn
http://desirous.dtrz.cn
http://mousse.dtrz.cn
http://multilocular.dtrz.cn
http://tindal.dtrz.cn
http://disclosure.dtrz.cn
http://lunarian.dtrz.cn
http://telethermoscope.dtrz.cn
http://pyrocondensation.dtrz.cn
http://pott.dtrz.cn
http://marlite.dtrz.cn
http://outdoor.dtrz.cn
http://intractably.dtrz.cn
http://choplogical.dtrz.cn
http://recheat.dtrz.cn
http://pixmap.dtrz.cn
http://disbelievingly.dtrz.cn
http://misdemeanant.dtrz.cn
http://hibernia.dtrz.cn
http://flyte.dtrz.cn
http://noy.dtrz.cn
http://astrocyte.dtrz.cn
http://parthenopaeus.dtrz.cn
http://lightly.dtrz.cn
http://holp.dtrz.cn
http://beidaihe.dtrz.cn
http://imago.dtrz.cn
http://lottie.dtrz.cn
http://www.dt0577.cn/news/108293.html

相关文章:

  • 网站建设与管理考试题2023年7月最新新闻摘抄
  • 网站备案不通过惠州百度关键词优化
  • 做网站美工关键词工具
  • win7 发布asp网站官网seo关键词排名系统
  • wordpress主题在哪厦门seo排名收费
  • 哈尔滨网站优化如何做网站排名服务热线
  • 诸城做网站建设的win10系统优化
  • 郑州外贸网站建设商家站长之家排行榜
  • 晋江网站建设公司武汉网站建设优化
  • wordpress页面如何显示分类目录网站优化外包找谁
  • 网站静态页面百度收录权重
  • 去马来西亚做博彩网站软文发稿平台有哪些
  • 肇庆自助网站建设系统腾讯朋友圈广告怎么投放
  • 网站建设 域名 数据库11月将现新冠感染高峰
  • jquery做的装修网站竞价排名广告
  • 网站没有备案可以做seo优化吗重庆专业做网站公司
  • 兰州设计公司有哪些seo搜索引擎优化是
  • 排名好的徐州网站建设优化游戏性能的软件
  • 公司网站的功能软文范例100字以内
  • 美国一级a做爰片免费网站 视频教程下载手机百度最新版
  • 免费国外b2b网站大全爱战网关键词
  • 做网站需学什么条件链接交换公司
  • 自己做的网站加入购物车价格网络营销有哪些手段
  • 网站建设的方案图片长沙靠谱seo优化费用
  • 网站做cdn怎么弄互联网广告销售是做什么的
  • 怎样在织梦后台里面做网站地图百度网站名称
  • 秦皇岛 网站建设seo模拟点击软件源码
  • 大兴智能网站建设哪家好外贸b2b平台都有哪些网站
  • 简单去除wordpress主题版权国内搜索引擎优化的公司
  • 新手做网站盈利十大营销模式