两个实现类实现同一个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是方法的方法名而不再是类名。

参考资料

  1. https://www.baeldung.com/spring-boot-testing
  2. https://dzone.com/articles/unit-and-integration-tests-in-spring-boot-2

springboot Service层单元测试的更多相关文章

  1. spring service层单元测试

    service层测试较简单,目前大多数测试主要是针对public方法进行的.依据测试方法划分,可以分为两种:基于mock的隔离测试和基于dbunit的普通测试. mock隔离测试 配置pom.xml ...

  2. springBoot service层 事务控制

    springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的方法上添加@Transactional ...

  3. SpringBoot—单元测试模板(controller层和service层)

    介绍 概述   在开发过程中,我们经常会一股脑的写各种业务逻辑,经常等全部大功告成的时候,打个jar包放环境里跑跑看看能不能通,殊不知在各个业务方法中已经漏洞百出,修复一个打一个包,再继续修复,这种效 ...

  4. 学习MVC之租房网站(四)-实现Service层并进行单元测试

    在上一篇<学习MVC之租房网站(三)-编写Eneity类并创建数据库>中,记录了编写Eneity类并采用CodeFirst的方式创建数据库的过程,接下来就到了Service层的实现了,并且 ...

  5. springboot 注册dao层 service 层

    可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...

  6. SpringBoot在自定义类中调用service层等Spring其他层

    解决方案: 1.上代码 @Component public class ServerHandler extends IoHandlerAdapter { @Autowired protected He ...

  7. 使用springboot实现一个简单的restful crud——02、dao层单元测试,测试从数据库取数据

    接着上一篇,上一篇我们创建了项目.创建了实体类,以及创建了数据库数据.这一篇就写一下Dao层,以及对Dao层进行单元测试,看下能否成功操作数据库数据. Dao EmpDao package com.j ...

  8. springboot Aop配置,并使用自定义注解annotation,并且拦截service层

    前言 用Spring Boot的AOP来简化处理自定义注解,并将通过实现一个简单的方法执行判断节点是否开始的状态示列源码. AOP概念 面向侧面的程序设计(aspect-oriented progra ...

  9. SpringBoot在Impl类中调用其它service层失败解决办法

    在AImpl.java文件中引用BImpl.java的方法,编译正常,运行到调用的地方,报空指针异常,跟踪到异常位置,发现service为空,也就是按照之前controller层通过@Autowire ...

随机推荐

  1. Mybatis的分支选择和In循环

    Mybatis的分支选择: <choose> <when test="patientNo != null and patientNo != ''"> and ...

  2. C++中的静态成员函数

    1,问完成的需求: 1,统计在程序运行期间某个类的对象数目: 1,静态成员变量满足了这个需求: 2,保证程序的安全性(不能使用全局变量): 3,随时可以获取当前对象的数目: 1,有没有什么特别的地方或 ...

  3. Linux.中断处理.入口x86平台entry_32.S

    Linux.中断处理.入口x86平台entry_32.S Linux.中断处理.入口x86平台entry_32.S 在保护模式下处理器是通过中断号和IDTR找到中断处理程序的入口地址的.IDTR存的是 ...

  4. Php 十六进制短浮点数转十进制,带符号位

    /** * 十六进制浮点型转为十进制 * @param String $strHex 十六进制浮点数 * @return 十进制 */ public static function hexToDecF ...

  5. mySQL部分疑问和小结(orale)

    2015/10/15 1.mysql语句: ALTER table scfz_xewp add BGR varchar(255) after KYR 2.创建触发器时:  --/   CREATE D ...

  6. Java调用DB的存储过程

    2015/12/7 使用数据库存储过程的java代码:   try {            con = (Connection) DBProxy.getConnection(null);       ...

  7. CentOS 7.3 环境配置java和tomcat开机启动

    Centos7下添加开机自启动服务和脚本  https://blog.csdn.net/GMingZhou/article/details/78677953 安装部分参考我的博文,仅参考他的开机启动部 ...

  8. 虚拟机设置静态IP地址

    前言 NAT连接方式只能配置一次,配置好子网掩码和网关IP后,虚拟机NAT连接的ip段都是同一个ip段 1.菜单栏选择 编辑 -> 虚拟网络编辑器,打开虚拟网络编辑器对话框,选择Vmnet8 N ...

  9. node 下载 解压 重命名

    <!doctype html><html> <head> <meta charset="utf-8"> <title>注 ...

  10. Java中JDBC连接池&JDBCTemplate

    数据库连接池 概念:其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归 ...