运行junit测试时发生NoSuchBeanDefinitionException

时间:2015-05-07 20:47:24

标签: java spring junit

以下是设置:

我正在测试我使用此处显示的Java Mail编写的电子邮件通知服务:

@Service
public class EmailNotificationService implements NotificationService {
    @Autowired
    private CertificateService service;

    @Override
    public boolean sendFeedback(String title, String feedback) throws NotificationException {

    // Code here
    }
    @Override
    public boolean sendQuestion(String title, String question) throws NotificationException {

    // Code here
    }
}

我的单元测试类是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:/service-commons/src/test/resources/service-commons.xml",
                   "file:/service-commons/src/test/resources/securityContext.xml",
                   "file:/service-commons/src/test/resources/mockUserProviderContext.xml" })
public class TestEmailNotificationService extends TestCase {

@Autowired
private EmailNotificationService emailServ;
@Resource
private WebApplicationContext context;

@Test
public void testSendFeedback() {
    try {
        boolean bool = emailServ.sendFeedback("feedbackTitle", "someFeedback");
        assertTrue(bool);
    } catch (NotificationException e) {
        e.printStackTrace();
        fail();
    }
}

@Test
public void testSendQuestion() {
    try {
        boolean bool = emailServ.sendQuestion("questionTitle", "someQuestion");
        assertTrue(bool);
    } catch (NotificationException e) {
        e.printStackTrace();
        fail();
    }
}

}

mockUserProviderContext.xml:

<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="simpleCertService" class="service.commons.defaults.CertificateService" />
<bean id="service" class="service.commons.defaults.EmailNotificationService" />

每当我尝试运行此单元测试时,我都会收到以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:252)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    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:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'service': Injection of resource dependencies failed; nested exception is    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)}
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    ... 25 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 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.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:457)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:435)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:559)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:305)
    ... 41 more

CertificateService类:

public class CertificateService implements CertificateUserService {

private static final Logger log = Logger.getLogger(SimpleCertificateService.class);

@Override
public User fetchUser(final X509Certificate certificate) {
    log.info("Fetching user for " + certificate.getSubjectDN().getName());
    return new SimpleUser(certificate.getSubjectDN().getName());
}

@Override
public User fetchUser(String name) {
    log.info("Fetching user for " + name);
    return new SimpleUser(name);
}

public class SimpleUser extends AbstractUser {


    private static final long serialVersionUID = 1L;


    public SimplUser(String username) {
        super(username, "User", "thing", "User", "T1222", false);
        this.emailAddress = "some@example.com";
        this.phoneNumber = "(123)123-1234";
    }

    @Override
    public void clearCache() {
        super.clearCache();
    }

}

}

更新

我意识到我没有导入两个上下文文件,我将其移至src / test / resources中,并显示在此处:

securityContext.xml

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

    <import resource="classpath:mongo-context.xml" />

    <!-- This html element specifies that we'll use annotation driven method 
        security throughout our application. -->
    <security:global-method-security
        secured-annotations="enabled" pre-post-annotations="enabled" />

    <!-- This element is what protects the various service and UI end points. 
        It specifies we'll use an x509 filter to pull out the subject principal common 
        name and use that to produce a given User object. -->
    <security:http auto-config="true" use-expressions="true">
        <security:csrf disabled="true" />
        <security:intercept-url pattern="/**"
            requires-channel="https" access="isAuthenticated()" />
        <security:x509 subject-principal-regex="(.*)"
            user-service-ref="userDetailsService" />
    </security:http>

    <!-- This bean is the authentication manager we'll use. -->
    <beans:bean id="userAuthManager"
        class="service.commons.security.AuthenticationManager" />

    <!-- The bean is a UserDetails service that will provide the User object 
        for a given request. -->
    <beans:bean id="userDetailsService"
        class="service.commons.security.userDetailsService" />

    <!-- This is the UserFactory object that will fetch a User from the SecurityContext. -->
    <beans:bean class="service.commons.security.userFactory"
        id="userFactory" />

    <!-- This bean represents the session scoped User object. We use the 
        factory bean to fetch it from the SecurityContext and then scope it to a 
        session and make it available to the processing thread. -->
    <beans:bean scope="session" factory-bean="userFactory"
        factory-method="getUser" id="user" class="service.commons.security.User">
        <aop:scoped-proxy />
    </beans:bean>

<beans:bean id="emailServ" class = "ral.service.commons.defaults.EmailNotificationService" />

    <!-- UserApplicationInfoService -->
    <beans:bean id="userInfoService"
        class="service.commons.user_info.UserApplicationInfoServiceImpl" />



</beans:beans>

服务commons.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"      xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">


    <!-- Scan for components in the service-commons library... -->
    <context:component-scan base-package="service.commons"></context:component-scan>

</beans> 

然后我意识到我需要将另一个项目中的另一个上下文文件导入securityContext.xml,以访问缺少的某些bean。

我现在遇到的问题是,当我运行测试时,我收到一个由SAXParser异常引起的IllegalStateException,并显示以下错误消息: cvc-complex-type.2.4.c:匹配的通配符是严格的,但是没有找到元素&quot; import&#39;的声明。我尝试更改schemaLocation,添加spring版本和调整命名空间,但我无法弄清楚为什么这个SAXParserException会被抛出。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

CertificateService是否具有您未显示的依赖项?

此外,Spring junit runner通常会创建GenericApplicationContext而不是WebApplicationContext。您需要添加@WebAppConfiguration来创建后者。