想象一下,你有一个应用程序,你想对它进行单元测试和功能测试(不是很难想象).你可能有一个抽象类,我们称之为AbstractTestClass,你的所有单元测试都会从中扩展.
AbstractTestClass看起来像这样(使用JUnit 4):
class AbstractTestClass {
boolean setupDone = false;
@Before
public void before() {
if(!setupDone) {
// insert data in db
setupDone = true;
}
}
}
这就是我正在努力的方向.我有另一个测试Web界面的抽象类:
class AbstractWebTestClass extends WebTestCase {
boolean setupDone = false;
@Before
public void before() {
if(!setupDone) {
// here, make a call to AbstractTestClass.before()
// init the interfaces
setupDone = true;
}
// do some more thing
}
}
它几乎是同一个类,除了它扩展到WebTestCase.这个设计可以让我在单元测试时获得与测试接口时相同的数据.
通常,在处理此类问题时,您应该优先考虑组合而不是继承或使用策略模式.
不幸的是,我不喜欢在这个特定场景中支持组合而非继承的想法,我不知道如何使用策略模式,可能存在设计缺陷,我无法完全看到解决方案.
我怎样才能设计这个架构以实现我的目标.
最佳答案 我将通过以下方式实现此目的:
class Example {
class LazyInitStrategy implements Runnable {
private final Runnable operation;
private boolean done = false;
LazyInitStrategy(Runnable operation) {
this.operation = operation;
}
@Override
public void run() {
if (!done) {
operation.run();
done = true;
}
}
}
private final class AbstractInit implements Runnable {
public void run() {
// insert data in db
}
}
private final class AbstractWebInit implements Runnable {
public void run() {
// here, make a call to AbstractTestClass.before() init the interfaces
}
}
class AbstractTestClass {
final LazyInitStrategy setup = new LazyInitStrategy(new AbstractInit());
@Before
public void before() {
setup.run();
// do some more thing
}
}
class AbstractWebTestClass extends WebTestCase {
final LazyInitStrategy setupInfo = new LazyInitStrategy(new AbstractWebInit());
@Before
public void before() {
setupInfo.run();
// do some more thing
}
}
}
当然这是一个非常简单的解决方案,但它应该消除if / else逻辑重复,以检查设置是否已完成.使用Runnable是可选的,我这样做只是为了演示目的,在阅读世界中你可能会使用另一个界面.