我想定义一个抽象基类来定义通用可重用测试用例,我希望在测试各种API时一遍又一遍地执行这些测试用例。这个想法是定义一次测试,然后我可以从通用测试继承来获得测试定义,我所有的测试代码都要执行测试执行的具体细节。这样我就不会错过好的测试用例,我不需要重新发明轮子,也不需要在数十个地方进行更改,当我想要另一个好的测试用例进行测试时。从调用堆栈中检索最顶级注释的函数
实质上,我正在做参数化测试,其中的参数是在基类中定义的。预期的结果也在基类中定义。但是,有时需要覆盖预期的结果。例如,普通的字符串字段可能允许任何字符,而对象名字段可能(或者在我的情况下)限制哪些字符是合法的。例如,一个字符串字段允许“?”在该值中,名称字段没有。
我想弄清楚在基类中定义参数ONCE的干净方式,并且只定义了一次预期的结果,但是在上下文需要它的实现类中覆盖它。
我的问题是,当你重写一个方法时,你必须替换它的实现。你不能只替换它的一部分。我想在不覆盖参数部分的情况下替换预期的结果。我也不认为它是一种干净或理想的解决方案,可以将每个测试分解为两种方法,一种提供参数,另一种定义预期行为。
我正在考虑的一个选项是使用注释来定义预期结果。然后我可以重写注释,然后将实现委托给基类实现。只要基类使用注释来决定如何表现,它就应该起作用。
例如:(伪代码,而不是真正的Java)
abstract class foo {
@fubar(true)
void test1() { doSomething(param1) }
@fubar(true)
void test2() { doSomething(param2) }
@fubar(false)
void test3() { doSomething(param3) }
boolean isFubar(void) { ... } // generic annotation grabber
void doSomething(p) {
if (isFubar())
doThis(p)
else
doThat(p);
}
// abstract methods to be defined in the implementing class
void doThis(p);
void doThat(p);
}
class bar extends foo {
// change the expected result for test2 only
@fubar(false)
void test2() { super.test2(); }
// define how to execute the tests
void doThis(p) { ... }
void doThat(p) { ... }
}
class baz extends bar {
// only changes the semantics of test3, nothing else
@fubar(true)
void test3() { super.test3() }
}
考虑到这种层次,foo.test1()
,bar.test1()
和baz.test1()
都做同样的事情。 foo.test2()
做一件事,而bar.test2()
和baz.test2()
做别的事情。同样,foo.test3()
和bar.test3()
做了一件事,但baz.test3()
会有所不同。
我可以使用注释来完成此行为吗?如果是这样,isFubar
会是什么样子?我还没有看到方法名称未知的这种反射的例子。
作为一个侧面说明,如果没有完成预期的行为更清洁的方式,我很乐意听到的是什么。
闻起来像一个可能的XY问题。您可能希望查看AOP,或尝试找到更多面向对象的方法。 – shmosel
请详细说明*你想要完成什么,而不是*如何*。按照你的代码片断,简单地重写'isFubar()'返回true或false,并完全丢弃注释会更有意义。 – shmosel
此外,您提出的问题是作为代码请求发生的,这是在此处皱起眉头。你有没有试图解决这个问题?你卡在哪里? – shmosel