springboot Service层单元测试
两个实现类实现同一个Service接口
public interface CustomUrlService {
List<ShopMetrics> getShopMetrics();
}
@Service
public class CustomUrlServiceImpl implements CustomUrlService {
@Override
public List<ShopMetrics> getShopMetrics() {
return null;
}
}
@Service
public class CustomUrlServiceImpl2 implements CustomUrlService {
@Override
public List<ShopMetrics> getShopMetrics() {
return Arrays.asList(new ShopMetrics(34L, 34L));
}
}
使用的时候如果使用接口作为类型,直接使用@Autowired是无法找到具体是哪个bean的,因为@Autowired默认是按照类型注入的,需要加上@Qualifier注解指定实现类的bean id,如果@Service中没有指定bean id(bean name),默认是类名的首字母小写作为bean name。当然也可以使用@Resource注解,它默认是by name 注入的,所以变量名需要和待注入的实现类的bean name保持一致,如下所示:
@Autowired
@Qualifier("customUrlServiceImpl")
private CustomUrlService customUrlServiceImpl;
@Resource
private CustomUrlService customUrlServiceImpl2;
@TestConfiguration
我之前在springboot中写单元测试喜欢全部按照下面这种来写测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomUrlServiceImplTest {}
但是@SpringBootTest是把整个spring容器启动起来,然后把测试环境给你准备好,这样也是可以的,但是有时候只是显得有点有点笨重,看日志就知道整个应用不管和这个单元测试有关没关的都被启动了,而我们只是为了跑一个单元单元测试。
看了参考资料1之后,我才知道了单元测试不一定需要启动整个应用,层与层之间也可以并且应该隔离测试。如果上层测试需要用到下层的依赖,就使用mock的方式构造一个依赖。比如测试DAO层可以使用@DataJpaTest注解;测试controller层可以使用@WebMvcTest;测试Service层可以使用@TestConfiguration把需要用到Bean依赖进来。下面是测试Service层的一个例子:
@RunWith(SpringRunner.class)
public class CustomUrlServiceImplTest {
@TestConfiguration
static class prepareCustomServices{
@Bean
public CustomUrlService getCustomUrlServiceImpl() {
return new CustomUrlServiceImpl();
}
@Bean
public CustomUrlService getCustomUrlServiceImpl2() {
return new CustomUrlServiceImpl2();
}
}
@Autowired
@Qualifier("getCustomUrlServiceImpl")
private CustomUrlService customUrlServiceImpl;
@Resource
private CustomUrlService getCustomUrlServiceImpl2;
@Test
public void getShopMetrics() {
assertNull(customUrlServiceImpl.getShopMetrics());
assertNotNull(getCustomUrlServiceImpl2.getShopMetrics());
}
}
现在再运行@Test标注的单元测试就不会启动整个springboot容器中了。这里面需要注意的是使用 @Bean放入到spring容器的的bean的默认id是方法的方法名而不再是类名。
参考资料
- https://www.baeldung.com/spring-boot-testing
- https://dzone.com/articles/unit-and-integration-tests-in-spring-boot-2
springboot Service层单元测试的更多相关文章
- spring service层单元测试
service层测试较简单,目前大多数测试主要是针对public方法进行的.依据测试方法划分,可以分为两种:基于mock的隔离测试和基于dbunit的普通测试. mock隔离测试 配置pom.xml ...
- springBoot service层 事务控制
springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的方法上添加@Transactional ...
- SpringBoot—单元测试模板(controller层和service层)
介绍 概述 在开发过程中,我们经常会一股脑的写各种业务逻辑,经常等全部大功告成的时候,打个jar包放环境里跑跑看看能不能通,殊不知在各个业务方法中已经漏洞百出,修复一个打一个包,再继续修复,这种效 ...
- 学习MVC之租房网站(四)-实现Service层并进行单元测试
在上一篇<学习MVC之租房网站(三)-编写Eneity类并创建数据库>中,记录了编写Eneity类并采用CodeFirst的方式创建数据库的过程,接下来就到了Service层的实现了,并且 ...
- springboot 注册dao层 service 层
可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...
- SpringBoot在自定义类中调用service层等Spring其他层
解决方案: 1.上代码 @Component public class ServerHandler extends IoHandlerAdapter { @Autowired protected He ...
- 使用springboot实现一个简单的restful crud——02、dao层单元测试,测试从数据库取数据
接着上一篇,上一篇我们创建了项目.创建了实体类,以及创建了数据库数据.这一篇就写一下Dao层,以及对Dao层进行单元测试,看下能否成功操作数据库数据. Dao EmpDao package com.j ...
- springboot Aop配置,并使用自定义注解annotation,并且拦截service层
前言 用Spring Boot的AOP来简化处理自定义注解,并将通过实现一个简单的方法执行判断节点是否开始的状态示列源码. AOP概念 面向侧面的程序设计(aspect-oriented progra ...
- SpringBoot在Impl类中调用其它service层失败解决办法
在AImpl.java文件中引用BImpl.java的方法,编译正常,运行到调用的地方,报空指针异常,跟踪到异常位置,发现service为空,也就是按照之前controller层通过@Autowire ...
随机推荐
- Spring IOC DI AOP 的简单理解及应用
Spring两大特性:IOC 和AOP.IOC 控制反转,AOP 面向切面编程 spring 核心容器的主要组件时Bean工厂(BeanFactory) ,Bean 工厂使用控制反转模式来降低程序代码 ...
- json模块 pickle 模块 collections 模块 openpyxl 模块
json模块 json 模块是一个系列化模块 一个第三方的特殊数据格式 可以将python数据类型----> json 数据格式 ----> 字符串 ----> 文件 其他语言想要使 ...
- poj3216 Prime Path(BFS)
题目传送门 Prime Path The ministers of the cabinet were quite upset by the message from the Chief of Sec ...
- Nacos-服务注册地址为内网IP的解决办法
最近在使用Spring Cloud Alibaba这一套微服务解决方案,但是在服务注册的时候,网关死活找不到微服务地址,自己的微服务通过网关怎么也访问不到. 查找原因 仔细一查才发现,网关去访问了一个 ...
- 使用while循环实现菜单
- vue-router中的router-link的active-class
vue-router中的router-link的active-class 在vue-router中要使用选中样式的方法有两种: 1.直接在路由js文件中配置linkActiveClass 2.在r ...
- 浅谈CICD持续集成、持续部署的流程(转)
Jenkins是一个比较流行的持续集成工具GitLab是存储镜像的镜像仓库由客户端将代码push推送到git仓库,gitlab上配置了一个webHook的东西可以触发Jenkins的构建.进入到Jen ...
- excel acm 高校排名(hdoj)
其实写一个程序是最方便的... 不用每次进行很多次操作. 当然,能获得后台的数据更好…… e.g. 链接: https://pan.baidu.com/s/1a7s85oaKGam1-0mJ2v39u ...
- python--MySql(外键约束、多表查询(*****))
两张表之间的关系: 一对一(两张表可以合并成一张表) 一对一用的比较少,多对一对外键设置unique约束可以实现一对一 一对多(例如:每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任) 多 ...
- CSS分组和嵌套选择器
CSS 分组 和 嵌套 选择器 分组选择器 在样式表中有很多具有相同样式的元素.直线模组哪家好 h1 { color:green; } h2 { color:green; } p { ...