java 测试 Spring AOP 方面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1251317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:49:10  来源:igfitidea点击:

Testing a Spring AOP Aspect

javaspringspring-aop

提问by Robert Munteanu

When writing aspects, how can I test that they do match and that they are invoked when I want them to?

在编写方面时,我如何测试它们是否匹配以及在我想要它们时调用它们?

I'm using @Aspectdeclarations with Spring 2.5.6.

我在@AspectSpring 2.5.6 中使用声明。



I don't care about the functionality, that's extracted and tested otherwise.

我不关心功能,否则会被提取和测试。

采纳答案by Robert Munteanu

I ended up creating something which is a bit of an integration test, in the following way:

我最终通过以下方式创建了一些有点像集成测试的东西:

Created a Spring-aware JUnit test

创建了一个 Spring-aware JUnit 测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "aspects-test.xml" })
public class SomeAspectTest {

}

Created a spring configuration for this test which:

为此测试创建了一个弹簧配置,其中:

  • enables @AspectJ usage;
  • configures my aspect with dummy dependencies
  • declares a bean which should be picked up by the aspect

    <aop:aspectj-autoproxy />
    <bean class="SomeAspect">
        <property name="userDetailsSource">
                <bean class="StubUserDetailsSource"/>
        </property>
    </bean>
    <bean class="DummyService"/>
    
  • 启用@AspectJ 使用;
  • 使用虚拟依赖项配置我的方面
  • 声明一个应该被切面接收的bean

    <aop:aspectj-autoproxy />
    <bean class="SomeAspect">
        <property name="userDetailsSource">
                <bean class="StubUserDetailsSource"/>
        </property>
    </bean>
    <bean class="DummyService"/>
    

In the unit test I retrieve the dummy service and invoke its methods

在单元测试中,我检索了虚拟服务并调用了它的方法

@Autowired
private DummyService _dummyService;

@Test(expected = ApplicationSecurityException.class)
public void adminOnlyFails() throws ApplicationSecurityException {

    _dummyService.adminOnly();
}

回答by Rich Seller

There's three different things to test here:

这里有三个不同的东西要测试:

  1. Are your pointcuts matching what you expect?
  2. Do your advice reference the right pointcut?
  3. Does the advice do as you expect?
  1. 您的切入点是否符合您的预期?
  2. 您的建议是否引用了正确的切入点?
  3. 建议是否如您所愿?

To test the pointcuts, you can define some test types that have the same package/type/method signatures as the intended "real" targets, then define a test advice against the pointcuts to ensure they are matched (also define some types that shouldn't be matched to ensure the pointcuts aren't too liberal). I usually do this by defining the advice to do a callback to a method in the test target, setting a flag, then assert the flag was set.

要测试切入点,您可以定义一些与预期的“真实”目标具有相同包/类型/方法签名的测试类型,然后针对切入点定义测试建议以确保它们匹配(还定义一些不应该t 进行匹配以确保切入点不太自由)。我通常通过定义对测试目标中的方法进行回调的建议,设置一个标志,然后断言设置了该标志来做到这一点。

To test the advice is trickier. I tend to delegate all the advice body to a normal method, then focus on testing the method rather than the advice.

测试建议比较棘手。我倾向于将所有的建议主体委托给一个普通的方法,然后专注于测试方法而不是建议。

If you've done that, the only missing part is that your advice is applied to the correct pointcuts and actually calls the methods. If you're concerned this might be a problem you can do this by creating anotheraspect that matches your advice execution and sets a flag to show the expected delegated method was invoked by the aspect, and override the method to do nothing.

如果您已经这样做了,唯一缺少的部分是您的建议应用于正确的切入点并实际调用方法。如果您担心这可能是一个问题,您可以通过创建另一个方面来匹配您的建议执行并设置一个标志来显示方面调用了预期的委托方法,并覆盖该方法不执行任何操作。