两个实现类实现同一个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. Jquery中input:type=radio的监听,获取设置值

    一.html <div id='demo'> <input type='radio' name='sex' value='男' > <input type='radio' ...

  2. C#虚方法和抽象方法的区别

    一,如下例子 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespa ...

  3. javascript基础六(事件对象)

    1.事件驱动     js控制页面的行为是由事件驱动的.          什么是事件?(怎么发生的)     事件就是js侦测到用户的操作或是页面上的一些行为       事件源(发生在谁身上)   ...

  4. Linux面试基础(二)

    Linux常用目录——存放 /bin  所有用户可以使用的可执行文件 /sbin  新管理员使用的执行文件 /boot  Linux内核映像文件和与引导加载有关的文件 /dev   设备文件 /etc ...

  5. 转载 初学者必看——最简单最清晰的Struts2项目搭建流程

    https://blog.csdn.net/key0323/article/details/50773499 在项目中想要使用Struts2框架,我该怎么做?从哪里开始?这是我的疑惑,我想也是很多初学 ...

  6. C++ 使用老牌库xzip & unzip对文件进行压缩解压

    原文链接 https://www.codeproject.com/Articles/7530/Zip-Utils-clean-elegant-simple-C-Win https://www.code ...

  7. PHP clearstatcache() 函数

    定义和用法 clearstatcache() 函数清除文件状态缓存. PHP 会缓存某些函数的返回信息,以便提供更高的性能.但是有时候,比如在一个脚本中多次检查同一个文件,而该文件在此脚本执行期间有被 ...

  8. stat函数学习

    stat函数组 前面介绍的通过ls命令查看到的文件信息,都可以使用stat函数组提取出来• stat函数组– 使用命令man stat查看相关文档• 函数int stat(const char *pa ...

  9. 调用windows的复制文件对话框

    function CopyFileDir(sDirName: String; sToDirName: String): Boolean; var fo: TSHFILEOPSTRUCT; begin ...

  10. cms网站模板收集

    Dedecms模板 1.魔客吧  -----  dedecms .wordpress .discuz.shopnc.ecshop等模板都有 eg: html5绿色响应式企业网页模板 2.绘艺素材 -- ...