如果抽象类中包含了具体实现的方法,那么使用抽象类测试(一)中的抽象类测试方式就很勉强了,因为抽象类的具体方法有可能被继承该抽象类的具体子类所覆盖,导致测试偏差现象发生。对于这样的测试场景,可以引入静态内部类进行抽象类变相实例化测试,这里引入Commodity抽象类实现这种设计,该类属性,抽象方法和实例方法的具体描述如下:
commodity_name属于Commodity类实例私有属性,用于记录Commodity类实例的name值
commodity_price属于Commodity类实例私有属性,用于记录Commodity类实例的price值
getCommodity()工厂方法,返回一个Commodity实例
changerName()改变Commodity实例名称
changerPrice()改变Commodity实例价格
getCommodityName()取得Commodity实例名称
getCommodityPrice()取得Commodity实例价格
setCommodityName()设置Commodity实例名称
setCommodityPrice()设置Commodity实例价格
Commodity抽象类具体代码如下:
package com.fastpoint;
public abstract class Commodity {
private String Commodity_name;
private double commodity_price;
public abstract Commodity getCommodity();// 返回一个Commodity实例
public void changerName(String newName) {
setCommodity_name(newName);
}
public void changerPrice(double newPrice) {
setCommodity_price(newPrice);
}
public String getCommodity_name() {
return Commodity_name;
}
protected void setCommodity_name(String commodity_name) {
Commodity_name = commodity_name;
}
public double getCommodity_price() {
return commodity_price;
}
protected void setCommodity_price(double commodity_price) {
this.commodity_price = commodity_price;
}
}
Commodity类是一个抽象的商品类,本身包含了工厂方法getCommodity()来返回任何一个继承该类的具体子类实例,其余6个方法映射为该抽象商品类的具体业务操作。使用Junit对Commodity类进行测试需要得到类的实例,但是该类属于抽象类无法实例化,这样就需要引入一个具体子类来继承Commodity类,然后使用Junit对他进行测试,CommodityTestCase测试驱动类具体代码入下:
package com.fastpoint;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CommodityTest {
Commodity comm;
static class Inner_Commodity extends Commodity {
public Commodity getCommodity() {
return new Inner_Commodity();
}
}
@Before
public void setUp() throws Exception {
comm = new CommodityTest.Inner_Commodity().getCommodity();
}
@After
public void tearDown() throws Exception {
}
@Test
public void testChangerName() {
comm.setCommodity_name("软件测试");
assertEquals("软件测试", comm.getCommodity_name());
}
@Test
public void testChangerPrice() {
comm.setCommodity_price(30.5);
assertEquals(30.5,comm.getCommodity_price(),0);
}
@Test
public void testGetCommodity_name() {
comm.changerName("面向对象测试");
assertEquals("面向对象测试", comm.getCommodity_name());
}
@Test
public void testGetCommodity_price() {
comm.changerPrice(20.5);
assertEquals(20.5,comm.getCommodity_price(),0);
}
}
CommodityTestCase类内部声明了一个静态类Inner_Commodity,该类继承了Commodity类来实现其类具体行为,CommodityTestCase类也是Inner_Commodity类的外围类。这样做的好处在于,每一个类都有对应的TestCase类,测试类层次清晰便于管理和回归。