是的,这是可能的。让我们假设您有一个硬连线的类,可能从数据库中获取一些东西,并希望通过一个方面来模拟它:
package de.scrum_master.aop.app;
public class HardWired {
private int id;
private String name;
public HardWired(int id, String name) {
this.id = id;
this.name = name;
}
public void doSomething() {
System.out.println("Fetching values from database");
}
public int getSomething() {
return 11;
}
@Override
public String toString() {
return "HardWired [id=" + id + ", name=" + name + "]";
}
}
然后有一个小驱动应用程序使用那个类(不是接口):
package de.scrum_master.aop.app;
public class Application {
public static void main(String[] args) {
HardWired hw = new HardWired(999, "My object");
System.out.println(hw);
hw.doSomething();
System.out.println(hw.getSomething());
}
}
输出如下:
HardWired [id=999, name=My object]
Fetching values from database
11
现在你定义你的派生模拟类,它应该替换原来的用于测试目的:
package de.scrum_master.aop.mock;
import de.scrum_master.aop.app.HardWired;
public class HardWiredMock extends HardWired {
public HardWiredMock(int id, String name) {
super(id, name);
}
@Override
public void doSomething() {
System.out.println("Mocking database values");
}
@Override
public int getSomething() {
return 22;
}
@Override
public String toString() {
return "Mocked: " + super.toString();
}
}
最后,您使用简单的切入点和建议定义了一个方面,以在每次构造函数调用期间替换原始值:
package de.scrum_master.aop.aspect;
import de.scrum_master.aop.app.HardWired;
import de.scrum_master.aop.mock.HardWiredMock;
public aspect MockInjector {
HardWired around(int p1, String p2) : call(HardWired.new(int, String)) && args(p1, p2) {
return new HardWiredMock(p1, p2);
}
}
输出根据需要更改:
Mocked: HardWired [id=999, name=My object]
Mocking database values
22
您对每个类和构造函数执行一次,就可以了。为了概括该方法,您需要连接点属性,并且取决于您想要走多远,也许是反射,但这在这里非常简单。享受!