解决@springboottest注解无法加载src/main/resources目录下文件

 更新时间:2022年01月19日 10:03:30   作者:FollowYourHeart2015  
这篇文章主要介绍了解决@springboottest注解无法加载src/main/resources目录下文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Springboot微服务框架是目前越来越流行的框架,省去了很多繁琐的xml配置。最近新启了个项目,采用SpringBoot框架从头搭建,中间也遇到过各种坑,现在先描述一下 Junit4单元测试之坑吧。

结论

@SpringBootTest注解,只会加载test路径下的资源文件(即xml配置),并不会加载main路径下的资源文件,这点很坑。。。

环境及问题描述

1.SpringBoot版本:2.0.0.RELEASE

2.通过项目入口类启动Application.main() OK,能正常处理web请求

3.启动单元测试,执行测试类

提示Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xx.xxx.service.SsoService' available

如下:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-02-02 16:26:10.537 ERROR 7812 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

A component required a bean of type 'com.xx.xxx.service.SsoService' that could not be found.


Action:

Consider defining a bean of type 'com.xx.xxx.service.SsoService' in your configuration.

2019-02-02 16:26:10.541 ERROR 7812 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@93b025] to prepare test instance [com.jd.id.activity.ControllerTest@b9178]

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:107) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:na]
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) [junit-rt.jar:na]
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:na]
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:na]

…………

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xx.xxx.service.SsoService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1509)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:506)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:484)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:618)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:177)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318)
    ... 41 more


Process finished with exit code -1

问题分析

1.首先com.xx.xxx.service.SsoService该类存在

并且项目正常启动时,并没有这个错误提示,那肯定是单元测试配置的有问题了,首先检查下相关的配置,@RunWith(SpringRunner.class)使用SpringRunner以便在测试开始的时候自动创建spring的应用上下文,没毛病。

@SpringBootTest(classes = 启动类.class)配置也没问题,网上有讨论说springboot 1.4以下版本,要使用@SpringApplicationConfiguration(classes = 启动类.class),而我的项目版本是2.0,显然这个配置也没毛病。

代码如下:

package com.xx.xxx.activity;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;

/**
 * 单元测试基类
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
//由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration。
@WebAppConfiguration
public class BaseTest
{
    @Before
    public void init() {
        System.out.println("开始测试----------------");
    }

    @After
    public void destory() {
        System.out.println("结束测试----------------");
    }
}

2.再看下pom文件的配置

引用了对应的test包,也没毛病

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${springboot.version}</version>
            <scope>test</scope>
        </dependency>

3.这个类是在src/main/resources目录下的资源文件里配置

即xml中配置的bean,而src/test下并没有resources目录,莫非是这个原因?于是乎在test目录下创建resources路径,并把xml文件拷贝至test对应的路径下,结果能够正常进行单元测试了,数据也写入到数据库中,终于松了口气 -

准备就此作罢,不想在这个问题上浪费时间了,但是再做考虑,这样做欠妥,毕竟我每次改完xml文件的配置,必须得拷贝到test目录对应的文件夹下,这拷来拷去,并不是最好的解决方案啊,能不能打包时,把src/main/resources的资源文件也拷贝到src/test/resources中?这样就不用手工拷贝了。

答案是:当然有了,看pom.xml配置:

<build>
        <finalName>id-web-activity-root</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
        <!--单元测试时引用src/main/resources下的资源文件-->
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
            <testResource>
                <directory>src/main/resources</directory>
            </testResource>
        </testResources>
    </build>

这时再去执行单元测试,正常执行,同时test-classes路径下已经有了xml资源配置文件,如下图:

打包前

打包后

单元测试的坑算是填了,再接着填其他坑吧。。。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java实现策略模式使用示例

    java实现策略模式使用示例

    在使用图像处理软件处理图片后,需要选择一种格式进行保存。然而各种格式在底层实现的算法并不相同,这刚好适合策略模式。编写程序,演示如何使用策略模式与简单工厂模式组合进行开发
    2014-02-02
  • Java中的CopyOnWriteArrayList解析

    Java中的CopyOnWriteArrayList解析

    这篇文章主要介绍了Java中的CopyOnWriteArrayList解析,ArrayList是非线程安全的,也就是说在多个线程下进行读写,会出现异常,既然是非线程安全,那我们就使用一些机制把它变安全不就好了,需要的朋友可以参考下
    2023-12-12
  • java实现左旋转字符串

    java实现左旋转字符串

    这篇文章主要为大家详细介绍了java实现左旋转字符串,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • java开发hutool HttpUtil网络请求工具使用demo

    java开发hutool HttpUtil网络请求工具使用demo

    这篇文章主要为大家介绍了hutool之HttpUtil网络请求工具使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • SpringBoot中的自动装配原理详解

    SpringBoot中的自动装配原理详解

    本文将通过在Spring中集成MyBatis和在SpringBoot中集成MyBatis为大家简单梳理自动配置过程,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • 基于Spring-Security自定义登陆错误提示信息

    基于Spring-Security自定义登陆错误提示信息

    这篇文章主要介绍了Spring-Security自定义登陆错误提示信息,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 解决执行maven命令时提示Process terminated的问题

    解决执行maven命令时提示Process terminated的问题

    这篇文章主要介绍了解决执行maven命令时提示Process terminated的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 为何修改equals方法时还要重写hashcode方法的原因分析

    为何修改equals方法时还要重写hashcode方法的原因分析

    这篇文章主要介绍了为何修改equals方法时还要重写hashcode方法的原因分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java中Final关键字的使用技巧及其性能优势详解

    Java中Final关键字的使用技巧及其性能优势详解

    这篇文章主要介绍了Java中Final关键字的使用技巧及其性能优势详解,Java中的final关键字用于修饰变量、方法和类,可以让它们在定义后不可更改,从而提高程序的稳定性和可靠性,此外,final关键字还有一些使用技巧和性能优势,需要的朋友可以参考下
    2023-10-10
  • 详解JNI到底是什么

    详解JNI到底是什么

    JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互
    2021-06-06

最新评论