我想知道如何单元测试抽象类,以及扩展抽象类的类。
我是否应该通过扩展抽象类来测试它,去掉抽象方法,然后测试所有的具体方法?然后只测试我重写的方法,并在单元测试中测试扩展抽象类的对象的抽象方法?
我是否应该有一个抽象测试用例,可以用来测试抽象类的方法,并在测试用例中为扩展抽象类的对象扩展该类?
注意,我的抽象类有一些具体的方法。
我想知道如何单元测试抽象类,以及扩展抽象类的类。
我是否应该通过扩展抽象类来测试它,去掉抽象方法,然后测试所有的具体方法?然后只测试我重写的方法,并在单元测试中测试扩展抽象类的对象的抽象方法?
我是否应该有一个抽象测试用例,可以用来测试抽象类的方法,并在测试用例中为扩展抽象类的对象扩展该类?
注意,我的抽象类有一些具体的方法。
当前回答
遵循@patrick-desjardins的回答,我实现了抽象和它的实现类@Test,如下所示:
抽象类- ABC.java
import java.util.ArrayList;
import java.util.List;
public abstract class ABC {
abstract String sayHello();
public List<String> getList() {
final List<String> defaultList = new ArrayList<>();
defaultList.add("abstract class");
return defaultList;
}
}
由于抽象类不能被实例化,但它们可以被子类化,具体类DEF.java如下:
public class DEF extends ABC {
@Override
public String sayHello() {
return "Hello!";
}
}
测试类来测试抽象方法和非抽象方法:
import org.junit.Before;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.contains;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;
public class DEFTest {
private DEF def;
@Before
public void setup() {
def = new DEF();
}
@Test
public void add(){
String result = def.sayHello();
assertThat(result, is(equalTo("Hello!")));
}
@Test
public void getList(){
List<String> result = def.getList();
assertThat((Collection<String>) result, is(not(empty())));
assertThat(result, contains("abstract class"));
}
}
其他回答
为了专门对抽象类进行单元测试,您应该出于测试目的派生它,test base.method()的结果和继承时预期的行为。
你通过调用一个方法来测试它,所以通过实现一个抽象类来测试它……
我为抽象类和接口所做的工作如下:我编写一个测试,将对象作为具体对象使用。但是在测试中没有设置类型为X的变量(X是抽象类)。这个测试类并没有添加到测试套件中,而是它的子类,它们有一个setup-方法,将变量设置为x的具体实现。这样我就不会重复测试代码。如果需要,未使用测试的子类可以添加更多的测试方法。
one way is to write an abstract test case that corresponds to your abstract class, then write concrete test cases that subclass your abstract test case. do this for each concrete subclass of your original abstract class (i.e. your test case hierarchy mirrors your class hierarchy). see Test an interface in the junit recipies book: http://safari.informit.com/9781932394238/ch02lev1sec6. https://www.manning.com/books/junit-recipes or https://www.amazon.com/JUnit-Recipes-Practical-Methods-Programmer/dp/1932394230 if you don't have a safari account.
也可以在xUnit模式中看到Testcase超类:http://xunitpatterns.com/Testcase%20Superclass.html
我反对“抽象”测试。我认为测试是一个具体的概念,没有抽象的概念。如果您有公共元素,请将它们放在辅助方法或类中供所有人使用。
至于测试抽象测试类,一定要问自己要测试的是什么。有几种方法,您应该找出适合您的场景的方法。您是否试图在子类中测试一个新方法?然后让您的测试只与该方法交互。测试基类中的方法吗?然后可能只针对该类有一个单独的fixture,并使用尽可能多的测试单独测试每个方法。
如果具体方法调用任何抽象方法,该策略将不起作用,您将希望分别测试每个子类的行为。否则,只要抽象类的具体方法与子类解耦,就可以像您所描述的那样扩展它并存根抽象方法。