我有三个包:
Foo提供了某些API
FooMySQL(取决于Foo)使用MySQL实现Foo API
FooPostgreSQL(取决于Foo)使用PostgreSQL实现Foo API
我有一堆junit测试,应该运行两次:再次执行FooMySQL,再次执行FooPostgreSQL。它们是相同的测试,因为对于这两种实现,API的行为应相同,只是设置和拆卸的方式略有不同。
问题:我应该在哪里定义这些测试?最合乎逻辑的地方似乎在Foo中。但是,在Foo中,它们不可执行,因为Foo不知道任何实现。我可以将它们放到FooMySQL中,但是看来我必须在FooPostgreSQL上有完整副本,因为Foo中定义的任何“测试”代码都无法通过FooMySQL等的maven依赖机制来引用。(是正确的,或者也许我想念一个把戏吗?)
另外,我可以创建一个单独的FooTests项目,FooMySQL和FooPostgreSQL测试可能依赖该项目。但这听起来也错了。有更好的主意吗?
最佳答案
您应该知道的第一件事是,您应该对单元进行测试是您的实现。总是。我认为您倾向于这样做,但是由于您提到有关测试Foo
的问题,因此我不确定,我只是想确保它已建立。
因此,我们只需要执行两次测试即可。
public abstract class FooTestBase {
protected abstract Foo getFoo();
@Test public void testBarMethod() {
// Do some tests calling getFoo().
}
}
public class FooMysqlTest extends FooTestBase {
@Before public void setUp() {
// Do stuff
}
@After public void tearDown() {
// Do stuff
}
@Override protected Foo getFoo() {
return new FooMysql();
}
}
public class FooPostgresqlTest extends FooTestBase {
@Before public void setUp() {
// Do stuff
}
@After public void tearDown() {
// Do stuff
}
@Override protected Foo getFoo() {
return new FooPostgresql();
}
}
由于您使用Maven,因此默认情况下
FooTestBase
不会被视为测试类,因为它不是以Test
开头或以Test
或TestCase
结尾。因此,您的测试将集中在FooTestBase
中,并将在每个子类中执行。您的测试将只编写一次,并且您的设置/拆卸将针对每个实现。