【问题标题】:@Autowired with JUnit tests@Autowired 与 JUnit 测试
【发布时间】:2014-10-20 09:58:26
【问题描述】:

我使用过 JUnit,但有些测试存在一些问题,这些测试在 Spring bean 中有 @Autowired 注释,当我引用它们时,@Autowired 的 bean 始终为 NULL。

示例代码如下:

     public class Test {

                 protected ApplicationContext ac;

                 @Before
                 public void setUp() {
                     ac = new FileSystemXmlApplicationContext("classpath:config/applicationContext.xml"
                     "classpath:config/test-datasources.xml");
                 }

                 @Test
                 public void testRun() throws Exception {
                        IManager manager =  (IManager)this.ac.getBean("manager");
                        manager.doSomething();
                 }
    }

    @Service
    public class Manager implements IManager {

            public boolean doSomething() throws Exception {
                 ParametersJCSCache parametersJCSCache = new ParametersJCSCache();
                 String paramValue = parametersJCSCache.getParameter("XPTO");
                 ...
            }
    }

    public class ParametersJCSCache extends SpringBeanAutowiringSupport {

          @Autowired
          private IParameterManager parameterManager;  //THIS IS NULL
    }

在调用 Manager 对象时,Spring 会生成代理,但在访问 @Autowired parameterManager 时,该对象为空,因此我无法测试此方法。

知道是什么原因造成的吗?为什么对象没有被注入?它在 Web 应用程序的上下文中运行良好,但在测试上下文中始终为 NULL。

【问题讨论】:

    标签: java spring junit autowired


    【解决方案1】:

    尝试使用 spring runner 来运行您的单元测试。

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:config/applicationContext.xml",
                     "classpath:config/test-datasources.xml"})
    public class MyTest {
    
       @Autowired private IManager manager;
    
       @Test public void someTest() {
         assertNotNull(manager);
       }
    }
    

    它只会在需要时加载配置一次,它会自动装配你的 junit 类

    【讨论】:

      【解决方案2】:

      我终于找到了解决问题的方法。 找到这个帖子 SpringBeanAutowiringSupport does not inject beans in jUnit tests 并执行类似 JUnit 测试的操作。

      【讨论】:

        【解决方案3】:

        在我看来,ParametersJCSCache 不是 Spring 托管 bean。您需要将其设为 Spring bean 并将其自动装配到 Manager 中

        @Service
                public class Manager implements IManager {
        
                        public boolean doSomething() throws Exception {
                             ParametersJCSCache parametersJCSCache = new ParametersJCSCache(); <-- You create a new (non Spring-managed) instance
                             String paramValue = parametersJCSCache.getParameter("XPTO");
                             ...
                        }
                }
        

        改为:

        @Service
        public class Manager implements IManager {
        
              @Autowired
              private ParametersJCSCache  parametersJCSCache; 
        
                public boolean doSomething() throws Exception {
                     String paramValue = parametersJCSCache.getParameter("XPTO");
                     ...
                }
        }
        
        @Component
        public class ParametersJCSCache extends JCSCache {
        
              @Autowired
              private IParameterManager parameterManager;  //THIS IS NULL
        }
        

        【讨论】:

        • 正确。这就是我使用 Autowired 的原因,如果 ParametersCache 是一个弹簧管理的 bean,我不需要自动装配 Manager bean。这适用于 Web 应用程序上下文。
        • 如果 ParametersJCSCache 是一个非 Spring 托管 bean,那么 Spring 究竟如何注入 IParameterManager?
        • 这很神秘,当我在网络上下文中调用相同的代码时,这很有效。使用 JUnit 不会得到相同的行为。并且 ParametersJCSCache 类扩展了 SpringBeanAutowiringSupport。忘记把它放在代码中。
        • 嗯,它并没有按照您认为的方式工作。
        • @Alan : 我们不能在测试中使用现有的自动装配配置吗?有什么办法吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-19
        • 2011-10-09
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多