1

我有一个测试用例,它依赖于“ticketDao”,如下所示:

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;

public class LfnSaleCancellationIntegrationTest extends BaseIntegrationTest {
  //@Resource(name = "baseTicketDao")
  private BaseTicketDao ticketDao;
  ....
  public void setTicketDao(@Qualifier("baseTicketDao") BaseTicketDao ticketDao) {
    this.ticketDao = ticketDao;
  }
}

和 BaseIntegrationTest 扩展自 spring 测试框架的 AbstractJpaTests,Spring 是 v3.0.5

运行此测试用例时,我遇到了类似的异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No unique bean of type [com.mpos.lottery.te.gamespec.sale.dao.BaseTicketDao] 
is defined: expected single matching bean but found 2: 
[baseTicketDao, extraballTicketDao]

我的项目进化了很久,其实我第一次遇到这个异常的时候,@Qualifier 就解决了。直到今天这个项目已经发生了很大的变化,但我真的不知道为什么@Qaulifier 和@Resource 不再工作了。

如果我删除'ticketDao'的依赖,测试用例将通过。我想知道弹簧配置是否有一些变化会导致这个异常?或者...我google了很多,但似乎没有其他人遇到过这样的问题,请给出您的意见,非常感谢!

4

2 回答 2

1

您正在使用AbstractJPATests哪个是旧弹簧测试框架的一部分和AbstractDependencyInjectionSpringContextTests. 默认情况下,注入不是基于注释的,但它会发现设置器和字段并尝试按类型注入。建议切换到更新的基于注释的测试,有关详细信息,请参阅 spring 文档。

作为一种解决方法,尝试更改自动连线模式。在测试构造函数中将其称为this.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),将您的字段重命名为 baseTicketDao 并删除 setter。

于 2013-03-26T10:54:37.063 回答
0

我知道原因。在我的新项目中,spring配置文件中有context:component-scan的声明,默认会注册4个BeanPostProcessor:

  • AutowiredAnnotationBeanPostProcessor(@Autowired)
  • RequiredAnnotationBeanPostProcessor(@Require)
  • CommonAnnotationBeanPostProcessor(JSR-250 注释,@Resource,@PostConstruct 等,@WebServiceRef)
  • PersistenceAnnotationBeanPostProcessor(@PersistenceUnit 和 @PersistenceContext)

在我的旧项目中,仅注册了默认的 BeanPostProcessor(internalAutoProxyCreator)。我的理解是 AutowiredAnnotationBeanPostProcessor 将始终按类型连接。无论如何,如果删除 context:component-scan,我的测试用例现在可以通过了。

事实上,我现在已经将我所有的测试用例迁移到 Spring 测试上下文框架中,并且必须声明 context:component-scan,否则@Autowired、@Resource 等注释将被忽略,并且您将自动获得大量 NullPointerException注入依赖。

注意:<context:annotation-config/>也会注册这 4 个 BeanPostProcessor。

于 2013-04-01T07:34:21.260 回答