使用Spring 3.1.2,JUnit 4.10.0,这两个版本都很新。我遇到的问题是我无法使用基于注释的自动装配工作。
下面是两个样本,一个没有使用注释的样本,工作正常。而第二个使用注释,这是行不通的,我找不到原因。我几乎遵循了spring-mvc-test的样本。
工作:
package com.company.web.api;
// imports
public class ApiTests {
@Test
public void testApiGetUserById() throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("/com/company/web/api/ApiTests-context.xml");
UserManagementService userManagementService = (UserManagementService) ctx.getBean("userManagementService");
ApiUserManagementController apiUserManagementController = new ApiUserManagementController(userManagementService);
MockMvc mockMvc = standaloneSetup(apiUserManagementController).build();
// The actual test
mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
}
}
失败,因为userManagementService
为空,未获得自动连接:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // should default to ApiTests-context.xml in same package
public class ApiTests {
@Autowired
UserManagementService userManagementService;
private MockMvc mockMvc;
@Before
public void setup(){
// SetUp never gets called?!
}
@Test
public void testGetUserById() throws Exception {
// !!! at this point, userManagementService is still null - why? !!!
ApiUserManagementController apiUserManagementController
= new ApiUserManagementController(userManagementService);
mockMvc = standaloneSetup(apiUserManagementController).build();
// The actual test
mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
}
}
请注意,上述两个测试类应使用相同的上下文配置,并在那里定义userManagementService。
ApiTests-context.xml中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="user"/>
<property name="password" value="passwd"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingResources="company.hbm.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
<context:annotation-config/>
<tx:annotation-driven/>
<context:mbean-export/>
<!-- tried both this and context:component-scan -->
<!--<bean id="userManagementService" class="com.company.web.hibernate.UserManagementServiceImpl"/>-->
<context:component-scan base-package="com.company"/>
<!-- Hibernate's JMX statistics service -->
<bean name="application:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/>
</beans>
并且UserManagementService(接口)以及UserManagementServiceImpl具有@Service
注释。
两个小问题/观察:即使它具有@Before注释,也不会调用setup()。此外,我注意到我的测试方法如果不是以'test'开头就不会被执行/识别,虽然我看到的所有spring-mvc-test样本都不是这样。
的pom.xml:
<dependency>
<groupId>org.junit</groupId>
<artifactId>com.springsource.org.junit</artifactId>
<version>4.10.0</version>
<scope>test</scope>
</dependency>
更新
问题只发生在我从maven运行测试时;当我在IDE(IntelliJ IDEA)中运行测试时,它没问题。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.3</version>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
答案 0 :(得分:6)
除非您进行组件扫描,否则不会发生自动装配。
为什么你在代码中注释了它?
<!--<context:component-scan base-package="com.company"/>-->
还有:junit。如果你在eclipse中,你可以直接进入pom的依赖树视图并过滤junit。检查你实际上是在使用那个版本而不是使用旧的junit。
编辑:好的我刚刚检查了你的配置,并且能够让它在这方面工作。我唯一的猜测是,你以某种方式运行它与一个坏的测试运行器,导致它使用错误的junit。
编辑2(求助):事实证明问题是因为您使用的是junit的自定义版本。 Surefire查找提供的junit库并且无法找到它。因此,它默认为junit 3,这是导致您的应用程序跳过加载配置的原因。
您可以明确指定自定义提供商,例如
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.3</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.12.3</version>
</dependency>
</dependencies>
</plugin>
但我发现它与自定义回购不兼容。如果可能,我建议使用junit的标准版本。
答案 1 :(得分:1)
尝试特定的上下文配置,例如
@ContextConfiguration(locations = {"/file1.xml", "/file2.xml" })
(仅显示如何在需要时将其与多个文件一起使用 - 一个可能就足够了)
编辑:您是否启用了此处提到的AutowiredAnnotationBeanPostProcessor? http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/
答案 2 :(得分:0)
我有同样的问题。我的@Autowire可以在我的IDE(SpringSource STS)中工作,但是当我使用Maven从命令行构建时,无法加载应用程序上下文。
问题在于我在pom.xml中的依赖项。我使用的是JUnit的Spring版本导致错误。我认为这是原帖的根本原因。我没有为任何Maven插件编写代码。
我改变了
<dependency>
<groupId>org.junit</groupId>
<artifactId>com.springsource.org.junit</artifactId>
<version>4.7.0</version>
</dependency>
到
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>