代码之家  ›  专栏  ›  技术社区  ›  jacky

junit spring-@BeforeClass在@ContextConfiguration之前运行

  •  0
  • jacky  · 技术社区  · 6 年前

    @WebAppConfiguration 以及 @BeforeClass setUp() 方法设置springcontext,以便springsecurity代码可以使用。
    但是自从 @上课前 在junit类注释之前运行 @webapp配置 @ContextConfiguration ,所以 @Autowired 属于 private WebApplicationContext wac 中为空 设置()
    那我就换衣服 @上课前 @Before 然后问题就解决了。
    @上课前 也能解决问题吗?


    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.ServletException;
    
    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.mock.web.MockServletContext;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.web.context.ContextLoaderListener;
    import org.springframework.web.context.WebApplicationContext;
    
    
    @ContextConfiguration(locations = {
        "classpath:/springTest/applicationContext_test.xml",
        "classpath:/applicationContext-security.xml",
        "classpath:/spring/applicationContext-repository.xml"
        })
    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    public class xxxTest {
    
      @Autowired
      private xxx target;
    
      @Autowired
      private LoginAuthenticationProvider loginAuthenticationProvider;
    
      @Autowired
      private WebApplicationContext wac;
    
      //set the context
      @BeforeClass
      public void setUp() throws ServletException {
        ServletContextListener listener = new ContextLoaderListener(wac);
        ServletContextEvent event = new ServletContextEvent(new MockServletContext(""));
        listener.contextInitialized(event);
      }
    
      //mock login(manually login)
      @Test
      public void test01() {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
        Authentication authentication = loginAuthenticationProvider.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    
        //other test code......
      }
    
    
    }
    

    错误消息

    2018-10-10 19:18:48,006 [main] INFO  [org.springframework.test.context.web.WebTestContextBootstrapper] - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@769e7ee8, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@5276e6b0, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@71b1176b, org.springframework.test.context.support.DirtiesContextTestExecutionListener@6193932a]
    2018-10-10 19:18:48,038 [main] INFO  [org.springframework.mock.web.MockServletContext] - Initializing Spring root WebApplicationContext
    2018-10-10 19:18:48,038 [main] INFO  [org.springframework.web.context.ContextLoader] - Root WebApplicationContext: initialization started
    2018-10-10 19:18:48,166 [main] INFO  [org.springframework.web.context.support.XmlWebApplicationContext] - Refreshing Root WebApplicationContext: startup date [Wed Oct 10 19:18:48 CST 2018]; root of context hierarchy
    2018-10-10 19:18:48,216 [main] INFO  [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
    2018-10-10 19:18:48,218 [main] ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
    org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
        at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
        at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
        at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
        at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:614)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:515)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
        at ericsson.rtm.service.chache.xxxTest.setUp(xxxTest.java:54)
        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:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:33)
        at mockit.integration.junit4.internal.MockFrameworkMethod.invokeExplosively(MockFrameworkMethod.java:44)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
        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:363)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
        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: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]**
        at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
        ... 34 more
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   roronoa_zoro    6 年前

    @BeforeClass是一个静态方法,这就是@Autowired variable给出null的原因。 1) 可以使用的一种方法是使用自定义布尔标志:

    private static boolean isInitialized = false;
    .....
    public void setUp() {
        if (isInitialized) {
            return;
        }
        // do the setup
        isInitialized = true;
    }
    

    2) 另一种方法(我没有尝试过,但理论上应该是可行的)是使用@BeforeAll注释。