vas*_*sco 82 java junit abstract-class
我是JUnit的Java测试新手.我必须使用Java,我想使用单元测试.
我的问题是:我有一个带有一些抽象方法的抽象类.但是有些方法并不是抽象的.如何使用JUnit测试此类?示例代码(非常简单):
abstract class Car {
public Car(int speed, int fuel) {
this.speed = speed;
this.fuel = fuel;
}
private int speed;
private int fuel;
abstract void drive();
public int getSpeed() {
return this.speed;
}
public int getFuel() {
return this.fuel;
}
}
Run Code Online (Sandbox Code Playgroud)
我想测试getSpeed()
和getFuel()
功能.
这个问题的类似问题在这里,但它没有使用JUnit.
在JUnit FAQ部分中,我找到了这个链接,但我不明白作者想用这个例子说些什么.这行代码是什么意思?
public abstract Source getSource() ;
Run Code Online (Sandbox Code Playgroud)
nsf*_*n55 102
如果你没有类的具体实现,那么方法不是static
测试它们的重点吗?如果你有一个具体的类,那么你将测试这些方法作为具体类的公共API的一部分.
我知道你在想什么"我不想一遍又一遍地测试这些方法,这就是我创建抽象类的原因",但我反驳的是单元测试的重点是允许开发人员进行更改,运行测试,并分析结果.这些变化部分可能包括重写你的抽象类的方法,既protected
和public
,这可能导致根本性的行为变化.根据这些更改的性质,它可能会影响您的应用程序以意外的方式运行,可能是负面的方式.如果您有一个好的单元测试套件,这些类型引起的问题在开发时应该是明显的.
Gro*_*uez 12
使用您发布的示例类,测试似乎没有多大意义getFuel()
,getSpeed()
因为它们只能返回0(没有setter).
但是,假设这仅仅是用于说明目的的简化示例,并且您有合理的理由在抽象基类中测试方法(其他人已经指出了其含义),您可以设置测试代码以便创建匿名基类的子类,它只为抽象方法提供虚拟(无操作)实现.
例如,TestCase
你可以这样做:
c = new Car() {
void drive() { };
};
Run Code Online (Sandbox Code Playgroud)
然后测试其余的方法,例如:
public class CarTest extends TestCase
{
private Car c;
public void setUp()
{
c = new Car() {
void drive() { };
};
}
public void testGetFuel()
{
assertEquals(c.getFuel(), 0);
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
(这个例子基于JUnit3语法.对于JUnit4,代码会略有不同,但想法是一样的.)
如果你还需要一个解决方案(例如,因为你有太多的抽象类实现,并且测试总是会重复相同的过程),那么你可以用一个抽象的工厂方法创建一个抽象的测试类,这个方法将通过实现考试班.这个例子适用于TestNG:
抽象测试类Car
:
abstract class CarTest {
// the factory method
abstract Car createCar(int speed, int fuel);
// all test methods need to make use of the factory method to create the instance of a car
@Test
public void testGetSpeed() {
Car car = createCar(33, 44);
assertEquals(car.getSpeed(), 33);
...
Run Code Online (Sandbox Code Playgroud)
实施 Car
class ElectricCar extends Car {
private final int batteryCapacity;
public ElectricCar(int speed, int fuel, int batteryCapacity) {
super(speed, fuel);
this.batteryCapacity = batteryCapacity;
}
...
Run Code Online (Sandbox Code Playgroud)
类ElectricCarTest
的单元测试类ElectricCar
:
class ElectricCarTest extends CarTest {
// implementation of the abstract factory method
Car createCar(int speed, int fuel) {
return new ElectricCar(speed, fuel, 0);
}
// here you cann add specific test methods
...
Run Code Online (Sandbox Code Playgroud)
小智 8
我将创建一个继承抽象类的 jUnit 内部类。它可以被实例化并可以访问抽象类中定义的所有方法。
public class AbstractClassTest {
public void testMethod() {
...
}
}
class ConcreteClass extends AbstractClass {
}
Run Code Online (Sandbox Code Playgroud)
小智 5
你可以做这样的事情
public abstract MyAbstractClass {
@Autowire
private MyMock myMock;
protected String sayHello() {
return myMock.getHello() + ", " + getName();
}
public abstract String getName();
}
// this is your JUnit test
public class MyAbstractClassTest extends MyAbstractClass {
@Mock
private MyMock myMock;
@InjectMocks
private MyAbstractClass thiz = this;
private String myName = null;
@Override
public String getName() {
return myName;
}
@Test
public void testSayHello() {
myName = "Johnny"
when(myMock.getHello()).thenReturn("Hello");
String result = sayHello();
assertEquals("Hello, Johnny", result);
}
}
Run Code Online (Sandbox Code Playgroud)