【问题标题】:Spring JUnit Test - Instantiation problemsSpring JUnit 测试 - 实例化问题
【发布时间】:2013-12-05 21:50:02
【问题描述】:

我有一个使用 maven 编译并部署在 tomcat 7 上的 Spring 应用程序。

我正在尝试使用 JUnit 4 实现一些测试用例。我成功地对应用程序的一部分进行了一些测试,但是当我想测试使用外部框架的两个部分时出现编译问题:Shiro 和 OIOSAML。由于这里没有 OIOSAML 社区,所以我将专注于 shiro,但我相信问题的原因是相同的。

当我尝试在 JUnit 测试中加载应用程序上下文时,我收到加载错误(请参阅下一个)。看起来某些依赖项无法在框架部分中加载/找到。以下是一些有用的信息:

Shiro 异常:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'authorization' defined in class path resource [test-context.xml]: 
Instantiation of bean failed; 
nested exception is org.springframework.beans.BeanInstantiationException: 
Could not instantiate bean class [myPackage.ShiroAuthorization]: 
Constructor threw exception; nested exception is org.apache.shiro.config.ConfigurationException: 
Unable to instantiate class [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] for object named 'ds'.  
Please ensure you've specified the fully qualified class name correctly.
            at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
            at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
            at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
            at myPackage.Test.init(Test.java:30)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            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.RunBefores.evaluate(RunBefores.java:24)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
            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:467)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
        Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [myPackage.ShiroAuthorization]: Constructor threw exception; nested exception is org.apache.shiro.config.ConfigurationException: Unable to instantiate class [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] for object named 'ds'.  Please ensure you've specified the fully qualified class name correctly.
            at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
            at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:110)
            at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
            ... 29 more
        Caused by: org.apache.shiro.config.ConfigurationException: Unable to instantiate class [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] for object named 'ds'.  Please ensure you've specified the fully qualified class name correctly.
            at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:151)
            at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:119)
            at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:161)
            at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:124)
            at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:102)
            at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:88)
            at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:46)
            at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123)
            at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47)
            at myPackage.ShiroAuthorization.<init>(ShiroAuthorization.java:31)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
            at java.lang.reflect.Constructor.newInstance(Unknown Source)
            at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
            ... 31 more
        Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] from the thread context, current, or system/application ClassLoaders.  All heuristics have been exhausted.  Class could not be found.
            at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:148)
            at org.apache.shiro.util.ClassUtils.newInstance(ClassUtils.java:164)
            at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:144)
            ... 45 more

Shiro.ini

...
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.url = jdbc:mysql://*******
...
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled=true
jdbcRealm.dataSource = $ds
...
securityManager.realms = $jdbcRealm,
...

OIOSAML 异常:

...Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/opensaml/xml/ConfigurationException...

测试用例

...
public static ApplicationContext context;
@BeforeClass
public static void  init() throws Exception {
    context = new ClassPathXmlApplicationContext("test-context.xml");
}

我尝试使用上下文文件,但没有任何帮助。奇怪的是,我可以成功测试 tomcat 7 的连接池,这表明依赖项已正确加载。

我提醒你,除了我想用 JUnit 测试它时,一切正常。

【问题讨论】:

  • 你的类路径中有mySql驱动吗?如果不是,您可能必须将其添加到您的 pom.xml
  • 它!...当我将它部署到 tomcat 上时,库是从 WEB-INF/lib 文件夹加载的。显然不是 JUnit。做出我能接受的答案。谢谢

标签: java spring junit shiro testcase


【解决方案1】:

您的类路径中有 mySql 驱动程序吗?可能就是这个问题。

【讨论】:

    【解决方案2】:

    尝试使用以下方法注释您的 JUnit 测试类:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {
        "classpath:/test-context.xml"
    })
    

    这会在运行 JUnit 测试时加载您的 applicationContext。

    确保您的 applicationContext xml 在您的类路径中。

    【讨论】:

    • 确实,这就是 czajek 所说的问题。感谢您的帮助。