【问题标题】:Spring 3 and Junit 4 NullPointerExceptionSpring 3 和 Junit 4 NullPointerException
【发布时间】:2015-05-20 07:36:02
【问题描述】:

我在设置基于 Spring 3 和 Junit 4 的单元测试时遇到问题

我的代码目前相当基本,如下所示

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)

public class PSTemplateDAOTests { 

    private static final Logger logger = Logger.getLogger(        
PSTemplateDAOTests.class.getName());

    @Autowired
    ApplicationContext ctx;


    @Test
    public void testone ()
    {
        logger.info("Run testone");     
    }

    @Test
    public void testtwo ()
    {
        logger.info("Run testtwo");
    }
}

但是,当我开始运行它时,我遇到了如下的 NPE:-

java.lang.NullPointerException
    at org.springframework.test.context.ContextLoaderUtils.resolveContextLoaderClass(ContextLoaderUtils.java:153)
    at org.springframework.test.context.ContextLoaderUtils.resolveContextLoader(ContextLoaderUtils.java:84)
    at org.springframework.test.context.ContextLoaderUtils.buildMergedContextConfiguration(ContextLoaderUtils.java:298)
    at org.springframework.test.context.TestContext.<init>(TestContext.java:100)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:117)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:119)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:108)
    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.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)

at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
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)

如果我注释掉 @ContextConfiguration 注释,测试将运行,但是我会遇到以下情况:-

May 20, 2015 8:28:29 AM org.springframework.test.context.TestContext  <init>
INFO: @ContextConfiguration not found for class [class    uk.gov.moj.ps.dao.PSTemplateDAOTests]
May 20, 2015 8:28:29 AM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
INFO: @TestExecutionListeners is not present for class [class uk.gov.moj.ps.dao.PSTemplateDAOTests]: using defaults.
2015-05-20 08:28:29 INFO  PSTemplateDAOTests:34 - Run testtwo
2015-05-20 08:28:29 INFO  PSTemplateDAOTests:27 - Run testone

这是有道理的,因为没有允许 Spring 设置环境的 ContextConfiguration 元素。

我还尝试了不同的 ContextConfiguration 设置,包括普通文件和位置元素,这两种设置都没有超过最初的 NPE 错误。

我正在使用 Eclipse Kepler 和 jre 1.7,尽管我也切换了 jre,但没有任何成功。

任何帮助将不胜感激。

好的 - 我意识到我的描述不够清楚,这是我关于 SO 的第一个问题,无论如何需要进一步澄清。

我知道上下文配置通常通过位置或简单路径配置文件路径,我已经尝试了这两种方法以及没有路径的默认值。

问题的关键在于@Contextconfiguration 会触发 NPE,而不管提供给它的是什么,实际上 spring 甚至似乎都没有正确初始化。

我希望这能让事情更清楚

【问题讨论】:

  • 你如何配置你的上下文配置?使用 xml 文件或注解?
  • 您不需要将@ContextConfiguration 指向它所在的位置吗?示例:@ContextConfiguration(locations = { "/META-INF/spring/applicationContext.xml" })

标签: java eclipse spring junit


【解决方案1】:

Spring Framework Reference Manual 中的大多数示例都明确定义了 XML 文件的位置,或用于填充应用程序上下文的 @Configuration 类。

你可以使用一个普通的@ContextConfiguration注解而不需要任何配置,但是默认的可能不是你所期望的:

如果您在 @ContextConfiguration 注释中省略了位置和值属性,TestContext 框架将尝试检测默认的 XML 资源位置。具体来说,GenericXmlContextLoader 根据测试类的名称检测默认位置。如果您的类名为 com.example.MyTest,GenericXmlContextLoader 从“classpath:/com/example/MyTest-context.xml”加载您的应用程序上下文。

恕我直言,您应该明确地将应用程序上下文的配置传递给@ContextConfiguration。来自同一文档的示例:

// use test.config.xml from classpath
@ContextConfiguration("/test-config.xml")
public class XmlApplicationContextTests {
    // class body...
}

// use TestConfig as a @Configuration class
@ContextConfiguration(classes = TestConfig.class)
public class ConfigClassApplicationContextTests {
    // class body...
}

【讨论】:

    【解决方案2】:

    我认为您不能像尝试那样自动装配 ApplicationContext,而且我不确定您为什么要这样做,尤其是在测试中。

    但如果你真的想,试试下面的代码:

    import java.util.logging.Logger;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.util.Assert;
    
    @ContextConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    public class PSTemplateDAOTests implements ApplicationContextAware {
        private static final Logger logger = Logger.getLogger(PSTemplateDAOTests.class.getName());
    
        private ApplicationContext ctx;
    
        @Test
        public void assertContextPreset() {
            Assert.notNull(ctx);
        }
    
        @Test
        public void testone() {
            logger.info("Run testone");
        }
    
        @Test
        public void testtwo() {
            logger.info("Run testtwo");
        }
    
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            ctx = applicationContext;
        }
    }
    

    正如其他人所说,您似乎也缺少一些应用程序上下文配置。您应该向ContextConfiguration 提供一个位置作为参数,或者在与测试相同的包中创建一个名为PSTemplateDAOTests-context.xml 的上下文文件。

    【讨论】:

      猜你喜欢
      • 2012-08-13
      • 2012-10-19
      • 2011-10-04
      • 2011-04-19
      • 2012-03-05
      • 1970-01-01
      • 2019-05-01
      • 2013-10-28
      • 1970-01-01
      相关资源
      最近更新 更多