为什么春天找不到我的豆子?

时间:2013-11-29 03:23:03

标签: java spring

我创建了一个接口和一个类:

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

3 个答案:

答案 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模型