我创建了一个接口和一个类:
public interface UserService {
List<User> listAll();
}
@Transactional
public class DefaultUserService implements UserService {
private String tableName;
public List<User> listAll() { someDao.listAllFromTable(tableName); }
public void setTableName(String tableName) { this.tableName = tableName; }
}
同样在我的应用程序上下文xml文件context.xml
中,我定义了:
<bean id="userService" class="mypackage.DefaultUserService">
<property name="tableName" value="myusers" />
</bean>
然后我想测试DefaultUserService
:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:context-test.xml"})
@TransactionConfiguration(transactionManager = "testTransactionManager")
@Transactional
public class UserServiceTest {
@Autowired
private DefaultUserService userService;
@Before
public void setup() {
userService.setTableName("mytesttable");
}
@Test
public void test() {
// test with userService;
userService.listAll();
}
}
请注意,它使用context-test.xml
,导入原始context.xml
:
<import resource="classpath:context.xml"/>
不幸的是,当测试开始时,spring抛出异常:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mypackage.UserServiceTest':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field:
private mypackage.DefaultUserService mypackage.userService
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [mypackage.DefaultUserService] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
我不确定哪里出错,为什么spring无法找到我定义的bean DefaultUserService
?
答案 0 :(得分:2)
尝试将班级DefaultUserService
替换为界面UserService
public class UserServiceTest {
@Autowired
private UserService userService;
....
}
答案 1 :(得分:2)
这是因为@Transactional
将bean放在实现UserService
接口的jdk代理之后,之后bean只能用作UserService
而不是DefaultUserService
。
见https://stackoverflow.com/a/18875681/241986。
您可以尝试使用属性占位符@Value("${someprop}")
设置表名,并在测试上下文中定义该属性,或者创建另一个将公开setTableName()
的接口,并将该帮助程序接口自动装入测试用例。
我不确定这个问题是否有任何简单的解决方案,我认为这个任务可以归入Spring测试上下文框架中bean重新定义的问题 Spring beans redefinition in unit test environment
答案 2 :(得分:1)
您尚未在getter
中为您的媒体资源tableName
定义implementing class
。弹出IOC
容器适用于POJO
模型