junit 未定义名为的Bean

lhcgjxsq  于 2022-11-11  发布在  其他
关注(0)|答案(5)|浏览(118)

我正在使用JUnit测试Spring的组件,抛出错误:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'wsVehicleService' is defined

这是我的测试类:

package com.zw.ws.service.impl;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/*.xml")    
public class WsVehicleServiceTest {

    @Autowired
    ApplicationContext ctx;

    @Test
    public void getHistoryAlarmInfo() throws Exception {
        try {
            String requestJson = "\"{\"VEHICLEID\":\"cae21196-cb66-4256-88a6-7cdfb23e2c78\",\"STARTTIME\":1476115200,\"ENDTIME\":1476201599,\"TYPE\":1}\"";
            WsVehicleService vehicleService = (WsVehicleService) ctx.getBean("wsVehicleService");
            vehicleService.getHistoryAlarmInfoImpl(requestJson);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }
}

这是将要测试的类:

@Component
public class WsVehicleService {

    public List<HistoryAlarmInfo> getHistoryAlarmInfo(String requestJson) {
        try {
            return getHistoryAlarmInfoImpl(requestJson);
        } catch (Exception e) {
            log.error(e);
            return null;
        }
    }
}

当JUnit运行到getBean时,抛出错误:No bean named 'wsVehicleService' is defined .哪里出了问题?我该怎么做才能纠正呢?
我尝试过的:
添加@ComponentScan("com.zw.ws.*")以扫描WsVehicleService类。
这是日志:

12:53:11.098]-[main]-[org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener]-{After test method: context [DefaultTestContext@58783f6c testClass = WsVehicleServiceTest, testInstance = com.zw.ws.service.impl.WsVehicleServiceTest@7577b641, testMethod = getHistoryAlarmInfo@WsVehicleServiceTest, testException = org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'wsVehicleService' is defined, mergedContextConfiguration = [MergedContextConfiguration@3a7b503d testClass = WsVehicleServiceTest, locations = '{classpath:/*.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null], method annotated with @DirtiesContext [false] with mode [null].}

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'wsVehicleService' is defined

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054)
    at com.zw.ws.service.impl.WsVehicleServiceTest.getHistoryAlarmInfo(WsVehicleServiceTest.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

            12:53:11.107]-[main]-[org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener]-{After test class: context [DefaultTestContext@58783f6c testClass = WsVehicleServiceTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@3a7b503d testClass = WsVehicleServiceTest, locations = '{classpath:/*.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null].}

PS:这不是XML配置,所有Bean都使用自动扫描。

ymzxtsji

ymzxtsji1#

在下列情况下,会掷回“未定义名为'xxx'的Bean”:

  • 您的Bean具有不同的名称。
  • 您的Bean实际上不在上下文中。

由于您没有更改Bean的默认名称,因此一定是没有正确加载Bean。
您需要指明在哪里扫描组件(xml config或@Configuration类),并在运行测试时加载组件。我将创建一个config类,然后将这个新的config类添加到ContextConfiguration注解中(如果您喜欢,也可以使用xml)。

@Configuration
@ComponentScan(basePackages = {"com.zw.ws"})
public class AppTestConfig {}

您的测试类则:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppTestConfig.class}) 
public class WsVehicleServiceTest {
...
}

您也可以使用@Autowire来旋转您的服务,并让Spring来执行连接工作。

hc2pp10m

hc2pp10m2#

1)第一种解决方案:
@ContextConfiguration初始化Spring上下文,默认情况下,在单元测试所在的同一包中查找Spring XML文件,该文件的文件名与类相同,后缀为“-context.xml
尝试在com.mycompany.annotation包中添加WsVehicleServiceTest-context.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

      <bean id="wsVehicleService"
          class="com.mycompany.annotation.WsVehicleService">
      </bean>

</beans>

删除后的Junit测试类(“classpath:/*.xml”):

package com.mycompany.annotation;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class WsVehicleServiceTest {

    @Autowired
    ApplicationContext ctx;

    @Test
    public void getHistoryAlarmInfo() throws Exception {
        try {
            WsVehicleService vehicleService = (WsVehicleService) ctx
                    .getBean("wsVehicleService");
            String hi = vehicleService.sayHi();
            System.out.println(hi);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }
}

**注意:**如果要使用@ContextConfiguration("classpath:/*.xml"),请确保将

<bean id="wsVehicleService"
              class="com.mycompany.annotation.WsVehicleService">
</bean>

在任何一个 *.xml文件中
2)第二种解决方案:
请确保将<context:annotation-config />放入xml文件中。此处不需要在xml文件中声明wsVehicleService bean。
通过在WsVehicleService上使用@Autowired修改测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/*.xml")   
public class WsVehicleServiceTest {

    @Autowired
    ApplicationContext ctx;

    @Autowired
    WsVehicleService wsVehicleService;

    @Test
    public void getHistoryAlarmInfo() throws Exception {
        try {
            String hi = wsVehicleService.sayHi();
            System.out.println(hi);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }
}

3)第三种解决方案:
您已经提到,您没有使用任何xml配置文件,并且您的异常告诉org.springframework.beans.factory.NoSuchBeanDefinitionException
您的WsVehicleService可能不存在于上下文中的一个原因是它可能被定义在Spring未扫描的包中。
请确保您的WsVehicleService存在于@ComponentScan("com.mycompany.annotation")包中。
1)带有注解@Configuration的应用程序配置类

package com.mycompany.annotation;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.mycompany.annotation")
public class AppConfig {

}

2)您的服务类别

package com.mycompany.annotation;

import org.springframework.stereotype.Component;

@Component
public class WsVehicleService {
    public String sayHi(){
        return "HI !!!!!!!!!!";
    }
}

3)Junit测试类

package com.mycompany.annotation;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class WsVehicleServiceTest {

    @Autowired
    ApplicationContext ctx;

    @Test
    public void getHistoryAlarmInfo() throws Exception {
        try {
            WsVehicleService vehicleService = (WsVehicleService) ctx
                    .getBean("wsVehicleService");
            String hi = vehicleService.sayHi();
            System.out.println(hi);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }
}

输出:

HI !!!!!!!!!!

欲了解更多信息,请参阅this
causes and possible solution for NoSuchBeanDefinitionException的更多参考

ffscu2ro

ffscu2ro3#

更改行

WsVehicleService vehicleService = (WsVehicleService) ctx.getBean(WsVehicleService .class);

@Component("wsVehicleService")
public class WsVehicleService{

//..

}
rqenqsqc

rqenqsqc4#

Spring注解代码

//main class    
//@Import(value=AppConfig.class)     
public class AppAnno {   
    public static void main(String[] args) {  
        AnnotationConfigApplicationContext ctx = new  
 AnnotationConfigApplicationContext(AppConfig.class);  
    TodayDate date = ctx.getBean("todayDate",TodayDate.class);   
System.out.println(date.getTodyDate());     
    }     
}    

@Configuration  
@ComponentScan(basePackages={"com.cb.service.anno","com.cb.dao.anno"})

根据您的基本包更改它

public class AppConfig {  
    @Bean 
public Date date(){    
return new Date();   
}    
}  

import java.util.Date;     
import javax.inject.Named;   
import org.springframework.beans.factory.annotation.Autowired;    
import org.springframework.stereotype.Component;   
@Component     
@Named("todayDate")//you have to add inject jar to your build path     
public class TodayDate {      
@Autowired    
    Date date;    
    public String getTodyDate(){     
    return date.toString( );    
    }     
}
4c8rllxm

4c8rllxm5#

如果我们使用基于Component的注解,则必须在configLocation .xml中提供如下的包路径:
<context:component-scan base-package="org.example.javaconfig"/>
这解决了我的问题

相关问题