为了模拟一些@Transactional
带注释的类,我必须为它们禁用Springs` aop代理创建。
如何配置我的spring启动应用程序以完全排除特定spring bean的任何代理创建,或者如何删除此bean的所有建议?
已经建议 Subclassing e.g. InfrastructureAdvisorAutoProxyCreator,但会引发Class name [null] is not a known auto-proxy creator class
错误。它似乎已在org.springframework.aop.config.AopConfigUtils
中静态初始化。
答案 0 :(得分:3)
作为一种解决方法,我使用弹簧AopUtils
打开代理:
@SuppressWarnings("unchecked")
public <T> T unwrapProxy(T bean) {
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
try {
bean = (T) advised.getTargetSource().getTarget();
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
return bean;
}
答案 1 :(得分:1)
不是原始问题的答案。但我认为你可以在这里使用@InjectMocks
mockito作为解决方案。即使标记为@Transactional
的类,它也应该有效。以下是关于主题的some questions。来自docs,
@InjectMock 标记应在其上执行注射的字段。
允许速记模拟和间谍注射。 最大限度地减少重复模拟和间谍注射。 Mockito将尝试仅通过构造函数注入,setter注入或属性注入按顺序注入模拟,如下所述。如果以下任何一种策略失败,那么Mockito就不会报告失败;即你必须自己提供依赖。
构造函数注入;选择最大的构造函数,然后使用在测试中声明的模拟来解析参数。 注意:如果找不到参数,则传递null。如果需要非可模拟类型,则构造函数注入不会发生。在这些情况下,您必须自己满足依赖关系。
Property setter injection ; mocks将首先按类型解析,然后,如果有多个相同类型的属性,则通过匹配属性名称和模拟名称。
注1 :如果你有相同类型(或相同的删除)的属性,最好用匹配的属性命名所有@Mock带注释的字段,否则Mockito可能会感到困惑注射不会发生。
注2 :如果@InjectMocks实例之前没有初始化并且有一个no-arg构造函数,那么它将使用这个构造函数进行初始化。
现场注射; mocks将首先按类型解析,然后,如果有多个相同类型的属性,则通过匹配字段名称和模拟名称。
注1:如果你有相同类型(或相同的删除)的字段,最好用匹配的字段命名所有@Mock带注释的字段,否则Mockito可能会感到困惑注射不会发生。
注2 :如果@InjectMocks实例之前没有初始化并且有一个no-arg构造函数,那么它将使用这个构造函数进行初始化。