我目前正在使用aspectj 开发一些监控工具。因为这个工具应该是技术独立的(尽可能),所以我没有使用 Spring 进行注入。但我希望我的方面能够经过单元测试。
方面示例:
@Aspect
public class ClassLoadAspect {
private Repository repository;
public ClassLoadAspect() {
repository = OwlApiRepository.getInstance();
}
@After("anyStaticInitialization()")
public void processStaticInitilization(JoinPoint jp) {
Class type = jp.getSourceLocation().getWithinType();
if (type.isInterface()) {
repository.storeInterfaceInitialization(type);
} else if (type.isEnum()) {
repository.storeEnumInitialization(type);
} else {
repository.storeClassInitialization(type);
}
}
@Pointcut("staticinitialization(*) && !within(cz.cvut.kbss.odra..*)")
public void anyStaticInitialization() {
}
public Repository getRepository() {
return repository;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
}
但是,我真的不知道如何构建单元测试(应该模拟存储库字段(使用mockito)),但我没有控制方面的创建,因此我无法手动设置依赖项。我应该调用什么来获取实例?或者还有一些其他场景如何对方面进行单元测试。
Thanks.
你说你找到了自己的方式来引入模拟对象 hacky。您到底不喜欢什么?您认为它会是什么样子?我只能猜测:
您是否不喜欢这样的事实:您在全球范围内替换了对OwlApiRepository.getInstance()
在你的元方面?然后,您可以专门限制模拟对象注入到方面的构造函数(我使用本机 AspectJ 语法,因为我对 POJO 注释样式感到不舒服):
public privileged aspect ClassLoadTestAspect {
static boolean active = true;
declare precedence : ClassLoadTestAspect, ClassLoadAspect;
pointcut classLoadAspect() :
if(active) &&
withincode(ClassLoadAspect.new()) &&
call(* OwlApiRepository.getInstance());
Object around() : classLoadAspect() {
return new MockRepository();
}
}
正如您还可以看到的,元(方面测试)方面的这种变体也有一个开关可以随意打开和关闭它。也许这也是你所不喜欢的。正如我所说,我猜测。根据您的反馈,我也许可以更具体地回答。
Edit:至于你关心的问题,我想我已经尽力解决了:
您不需要模拟支架。
该方面可以被激活(去激活)。很容易使其激活依赖于其他条件,因此它仅在您的测试环境中处于活动状态。如果这还不够,请在生产方面使用编译时编织,在测试方面使用加载时编织。这样,它的字节代码甚至不会出现在您的生产环境中。
我的版本不会在全球范围内取代任何东西,而是像一位优秀的外科医生一样,只在一个地方以微创方式进行切割。
我无法真正理解您对字节码操作的担忧,原因如下:您使用 AspectJ,即固有的字节码操作(编织)。您使用 Mockito 在运行时创建类。我也不明白你认为 AspectJ 的缺陷在哪里。您还没有解释您希望“语言的标准方法”如何表现,或者它应该提供什么接口来进行测试。即使你有,我也无法为你改变你自己选择的语言(AJ)和工具(Mockito)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)