Junit SpringAOP-@切入点:@测试方法的@Before建议不起作用
我的工作对象是:Junit SpringAOP-@切入点:@测试方法的@Before建议不起作用,junit,aop,aspectj,spring-aop,Junit,Aop,Aspectj,Spring Aop,我的工作对象是: Spring框架4.3.2 AspectJ 1.8.9 朱尼特 格拉德尔 该项目基于多个模块 在src/main/java(main)中,我有一些@Aspect类,它们按照预期的方式工作。我可以通过运行时和测试来确认它 现在我需要JUnit通过日志显示执行的@Test方法名 因此,在src/test/java(test)中,我有以下内容: class TestPointcut { @Pointcut("execution(@org.junit.Test * *()
- Spring框架4.3.2
- AspectJ 1.8.9
- 朱尼特
- 格拉德尔
src/main/java
(main)中,我有一些@Aspect
类,它们按照预期的方式工作。我可以通过运行时和测试来确认它
现在我需要JUnit通过日志显示执行的@Test
方法名
因此,在src/test/java
(test)中,我有以下内容:
class TestPointcut {
@Pointcut("execution(@org.junit.Test * *())")
public void testPointcut(){}
}
@Aspect
@Component
public class TestAspect {
private static final Logger logger = LoggerFactory.getLogger(TestAspect.class.getSimpleName());
@Before(value="TestPointcut.testPointcut()")
public void beforeAdviceTest(JoinPoint joinPoint){
logger.info("beforeAdviceTest - Test: {} - @Test: {}", joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName() );
}
}
观察第二个类有@方面
和@组件
,因此它被Spring识别
注意:我可以确认,如果我写错了@Pointcut
语法或表达式,我会出错
问题是当我执行我的@Test
方法时,对于testspect
类,@Before
建议永远不起作用
我在谷歌做了一项研究,发现@Pointcut(“execution(@org.junit.Test**())”)
模式是正确的。
即使我使用更明确的方法,例如:@Pointcut(value=“execution(public void com.manuel.jordan.controller.persona.*Test.*Test())”
,它也不起作用
考虑到我对Gradle
project(':web-27-rest') {
description 'Web - Rest'
dependencies {
compile project(':web-27-service-api')
testRuntime project(':web-27-aop')
testRuntime project(':web-27-aop').sourceSets.test.output
有什么遗漏或错误
阿尔法:
一种测试类别是:
- 服务器端使用
@参数
和
+@ClassRule
@Rule
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class})
@Transactional
public class PersonaServiceImplTest {
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE= new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Autowired
private PersonaService personaServiceImpl;
...
@Parameters
public static Collection<Persona[]> data() {
.....
});
}
...
@Test
@Sql(scripts={"classpath:....-script.sql"})
public void saveOneTest(){
....
}
您可以使用AspectJ编译或加载时编织作为SpringAOP代理的替代方案。在这种方法中,您将不会依赖spring上下文复杂的逻辑在代码中应用建议。方面代码将在编译或类加载阶段内联。 下面的示例显示了如何启用AspectJ编译时编织: pom.xml 此Maven配置启用AspectJ编译器,对类进行字节码后处理
org.aspectj
aspectjrt
org.codehaus.mojo
aspectj maven插件
1.6
真的
${java.source}
${java.target}
${java.target}
UTF-8
假的
假的
aspectj编译
编译
aspectj编译测试
测试编译
org.aspectj
aspectjrt
${aspectj.version}
org.aspectj
aspectjtools
${aspectj.version}
applicationContext.xml
此外,您可能需要将方面实例添加到Spring应用程序上下文中以进行依赖项注入
JUnit实例化您的测试类。因此,Spring没有参与,因此无法将AOP建议应用于测试实例 正如Sergey Bespalov所提到的,将AspectJ建议应用于测试实例的唯一方法是使用编译时或加载时编织。请注意,这不会在Spring中配置。Spring可用于为Spring管理的Bean配置AOP,但测试实例由测试框架管理(即,您的场景中的JUnit4) 但是,对于使用SpringTestContext框架的测试,我不建议使用AspectJ。相反,最好的解决方案是实现执行日志记录的自定义
TestExecutionListener
。然后,您可以通过@TestExecutionListeners
显式注册该TestExecutionListener
,或者让它为您的整个套件自动拾取。对于后者,请参阅《弹簧参考手册》测试章节中关于自动发现的讨论
问候,
Sam(SpringTestContext框架的作者)您能在这里提供您的测试类代码吗?Hello@SergeyBespalov代码已更新,请参阅
Alpha
部分。谢谢您可以尝试为测试类添加@EnableAspectJAutoProxy(proxyTargetClass=true)
注释。您好@SergeyBespalov,它不起作用。似乎“遗漏”了其他东西您正在使用哪种编织?是spring aop代理吗?非常有趣,想知道Gradle
的等价物是什么。让我做一个研究。你好,谢尔盖,考虑山姆的回答。也非常感谢您的宝贵支持。Sam的回答解释了这个问题,但奇怪的是为什么测试实例不是ApplicationContext的一部分。我想这可能是个虫子。我建议您尝试AspectJ编译器,它将解决您在站点上询问的这个和其他AOP问题。我在我所有的项目中都使用它,可以说它很好。是的,但奇怪的是为什么测试实例不是ApplicationContext的一部分,我也感到困惑,但在做了一个分析之后:我认为这不是一个bug,因为即使您看到带有一组Spring注释的测试类,它也不包含@配置,@组件
,@服务
等。因此,它既不是Spring创建的,也不是Spring处理的。它由JUnit创建,然后由于测试类中声明的当前注释,一些bean“可用”。通过Sam的建议,我完成了我的方法。我建议您尝试AspectJ编译器,它将解决您在网站上询问的AOP问题,让我们看看。但是我已经确认其中一个是一种bug,我已经在另一篇文章中给你写了一条关于JIRA的评论。不确定,但你能帮我一把吗?谢谢你的宝贵解释,山姆。我会研究一下你的建议。关于中的JUnit
@Transactional
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
public class PersonaDeleteOneControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
private ResultActions resultActions;
...
@BeforeClass
public static void setUp_(){
...
}
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void deleteOneHtmlGetTest() throws Exception {