Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AspectJ的JUnit测试_Java_Junit_Mockito_Aspectj_Spring Aop - Fatal编程技术网

Java AspectJ的JUnit测试

Java AspectJ的JUnit测试,java,junit,mockito,aspectj,spring-aop,Java,Junit,Mockito,Aspectj,Spring Aop,我正在尝试为自定义方面编写Junit测试。以下是方面类代码段: @Aspect @Component public class SampleAspect { private static Logger log = LoggerFactory.getLogger(SampleAspect.class); @Around("execution(* org.springframework.data.mongodb.core.MongoOperations.*(..)) || exe

我正在尝试为自定义方面编写Junit测试。以下是方面类代码段:

@Aspect
@Component
public class SampleAspect {

    private static Logger log = LoggerFactory.getLogger(SampleAspect.class);

    @Around("execution(* org.springframework.data.mongodb.core.MongoOperations.*(..)) || execution(* org.springframework.web.client.RestOperations.*(..))")
    public Object intercept(final ProceedingJoinPoint point) throws Throwable {
        logger.info("invoked Cutom aspect");
         return point.proceed();

    }

}
因此,只要jointpoint与切入点匹配,上述方面就会截取。工作正常

但我的问题是如何对该类进行单元测试。我有以下Junit测试:

@Test(expected = MongoTimeoutException.class)
    public void TestWithMongoTemplate() {
        //MongoDocument class
        TestDocument test = new TestDocument();

        ApplicationContext ctx = new AnnotationConfigApplicationContext(TestMongoConfigurationMain.class);
        MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);

        //this call is being intercepted by SampleAspect
        mongoTemplate.save(test);

    }
因此,Junit中我的
mongoTemplate.save(test)
samplespect
截取,因为它与切入点匹配。但是,在junits中(可能通过断言),当调用连接点时,如何确保我的
SampleSpect
正在拦截

我不能断言
intercept()
的返回值,因为它除了执行关节点之外没有什么特殊的功能。因此,我的Junit找不到任何区别,无论是按方面执行还是基于返回值的常规执行


任何关于方面测试的代码片段示例如果提供的话都会非常好。谢谢

我认为您尝试测试的是方面编织和切入点匹配。请注意,这将是一个集成而不是单元测试。如果你真的想单元测试你的方面逻辑,并且因为你已经用“mockito”标记了这个问题,我建议你这样做:写一个单元测试,模拟方面的连接点,或者它的其他参数,如果有的话。下面是一个稍微复杂一些的示例,其中包含一些方面内逻辑:

要按方面定位的Java类:

package de.scrum\u master.app;
公共类应用程序{
公共静态void main(字符串[]args){
新应用().剂量测定法(11);
新应用().剂量测量(-22);
新应用().剂量测定法(333);
}
公共无效剂量测定(整数){
System.out.println(“用数字做某事”+数字);
}
}
被测方面:

package de.scrum\u master.aspect;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
@面貌
公共类样本{
@围绕(“执行(*doSomething(int))和&args(number)”)
公共对象截获(最终处理JoinPoint thisJoinPoint,整数)抛出可丢弃{
System.out.println(此连接点+“->”+编号);
如果(数字<0)
返回thisJoinPoint.Procedure(新对象[]{-number});
如果(数量>99)
抛出新的运行时异常(“oops”);
返回此连接点。继续();
}
}
运行
Application.main(..)
时的控制台日志:

如您所见,方面传递11,否定-22,并抛出333的异常:

执行(void de.scrum_master.app.Application.doSomething(int))->11
用11号做点什么
执行(void de.scrum_master.app.Application.doSomething(int))->-22
用22号做点什么
执行(void de.scrum_master.app.Application.doSomething(int))->333
线程“main”java.lang.RuntimeException中的异常:oops
在de.scrum_master.aspect.samplespect.intercept(samplespect.aj:15)上
在de.scrum_master.app.Application.doSomething(Application.java:10)
位于de.scrum_master.app.Application.main(Application.java:7)
方面的单元测试:

现在我们真的想验证方面是否做了它应该做的事情,并覆盖所有执行路径:

package de.scrum\u master.aspect;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.junit.Rule;
导入org.junit.Test;
导入org.mockito.Mock;
导入org.mockito.junit.MockitoJUnit;
导入org.mockito.junit.MockitoRule;
导入静态org.mockito.mockito.*;
公共类抽样测验{
@统治
public MockitoRule MockitoRule=MockitoJUnit.rule();
@嘲弄
私有进程连接点进程连接点;
私有SampleSpect SampleSpect=新SampleSpect();
@试验
public void testPositiveSmallNumber()抛出可丢弃的{
SampleSpect.intercept(过程接合点,11);
//“继续()”只被调用一次
验证(proceedingJoinPoint,次数(1))。继续();
//永远不会调用“继续(对象[])”
验证(proceedingJoinPoint,never())。继续(null);
}
@试验
public void TestNegativeEnumber()抛出可丢弃的{
SampleSpect.截距(处理连接点,-22);
//从未调用“procedure()”
验证(proceedingJoinPoint,never())。继续();
//“继续(对象[])”只调用一次
验证(proceedingJoinPoint,次(1))。继续(新对象[]{22});
}
@测试(预期=RuntimeException.class)
public void testPositiveLargeNumber()抛出可丢弃{
SampleSpect.intercept(处理连接点,333);
}
}
现在运行这个简单的JUnit+Mockito测试,以便单独测试方面逻辑,而不是布线/编织逻辑。对于后者,您需要另一种类型的测试


附言:我只为你用了JUnit和Mockito。通常我只使用Spock及其内置的模拟功能<代码>;-)

对于在本文中寻找方面集成测试的任何人,我所做的是在方面中创建一个跟踪任何连接点行为的属性,然后在Junit中对该属性进行断言。这对我很有用。实际上,你不应该仅仅为了支持集成测试而向方面添加成员或手动簿记。这会使生产速度变慢。集成测试方面还有很多其他方法。也许这值得再问一个问题。如果您创建了一个,请随时通知我,我将尝试回答。@kriegaex。这里是链接。谢谢,我想模拟/测试ProceedingJoinPoint的值。我该怎么做呢?我上面的答案已经说明了如何嘲笑它。你能问得更准确些吗?请不要劫持一个旧问题,而是用一个真实的问题创建一个新问题,即至少由一个方面、一个目标类和一个我可以编译、运行和分析的测试组成的问题?什么