简体   繁体   English

运行单元测试时的Spring Context问题

[英]Spring Context issue while running unit test

I am running some unit tests using Spring and Mockito. 我正在使用Spring和Mockito运行一些单元测试。 I have configured the mocks in the springcontext.xml as follow: 我已经在springcontext.xml中配置了模拟,如下所示:

<bean id="featureEndpoint" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.company.blah.blah.FeatureEndpoint" />
</bean>

My test class is constructed as follow: 我的测试班级构造如下:

@ContextConfiguration(locations= {"/springcontext.xml"})
public class FeatureEndpointValidationTest extends JsonEndpointValidationTest {

    private FeatureEndpoint featureEndpoint;

    @BeforeClass
    public void setUp() {
        featureEndpoint = getBean("featureEndpoint");
        super.setEndpoint(featureEndpoint);
    }

    @Test
    .
    .
    .
}

When I run this test, getBean() throws an NPE because context is null. 当我运行此测试时,因为context为null,所以getBean()会抛出NPE。 HOWEVER, if I rename the test class to say TestEndpoint (or anything that does not have the string 'Feature', it runs perfectly fine. Im flummoxed with this behaviour. I have searched all other config files for any naming clashes but none of them have any bean that contains the name 'feature'. Any clues as to why this is happening? 但是,如果我将测试类重命名为TestEndpoint(或没有字符串'Feature'的任何东西,它运行得很好。我对此行为感到困惑。我已经在所有其他配置文件中搜索了任何命名冲突,但没有发现任何冲突)有任何包含“功能”名称的bean。有关为什么发生这种情况的任何线索?

Here is the trace of the exception thrown: 这是引发异常的痕迹:

java.lang.NullPointerException
    at com.foo.bar.UnitTest.getBean(UnitTest.java:14)
    at com.foo.bar.service.api.rest.FeatureEndpointValidationTest.setUp(FeatureEndpointValidationTest.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:580)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:398)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:145)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:82)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:167)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:104)
    at org.testng.TestRunner.runWorkers(TestRunner.java:712)
    at org.testng.TestRunner.privateRun(TestRunner.java:582)
    at org.testng.TestRunner.run(TestRunner.java:477)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:324)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:319)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:292)
    at org.testng.SuiteRunner.run(SuiteRunner.java:198)
    at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:821)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:788)
    at org.testng.TestNG.run(TestNG.java:708)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:62)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:141)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)

Thanks 谢谢

You're using sprint-test, which is good. 您正在使用sprint-test,这很好。 Try setting up your test like this: 尝试像这样设置测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:springcontext.xml)
public class MyTest {

    @Autowired
    private FeatureEndpoint featureEndpoint;

    @Test
    public void testSomething() { }

}

Using the @Autowired annotation with the Spring JUnit runner class, all autowired variables will be initialized to their corresponding bean of the same type. 在Spring JUnit运行器类中使用@Autowired批注,所有自动装配的变量将被初始化为它们对应的相同类型的bean。 You can also use @Qualifier("featureEndpoint") to specify a bean name. 您也可以使用@Qualifier("featureEndpoint")指定bean名称。

If you simply want access to the context, implement ApplicationContextAware which contains a setApplicationContext method. 如果您只想访问上下文,请实现包含setApplicationContext方法的ApplicationContextAware

Also, if you want to verify beans, you can implement InitializingBean , which, in a spring container, will be called after instantiation and initialization, where you can assert whether or not FeatureEndpoint is not null. 另外,如果要验证Bean,则可以实现InitializingBean ,该实例将在实例化和初始化之后在弹簧容器中调用,可以在其中声明FeatureEndpoint是否不为null。

The key to this whole equation though is to use the SpringJUnit4ClassRunner runner class. 但是,整个方程式的关键是使用SpringJUnit4ClassRunner类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM