OOP
的一个很好的机制是使用抽象类,抽象类是不能被实例化的,只能提供给派生类一个接口。设计人员通常使用抽象类来强迫实现人员从基类派生,这样可以确保新的类包含一些期待的功能。
在
Junit
对抽象类的测试中再次引入工厂设计模式,其测试思想是:抽象类不能被实例化,所以使用具体类测试抽象类是不可以的。因此,构造抽象类的测试类必须也是抽象的。该类需要强制声明两种类型的抽象方法。第一类抽象方法即工厂方法,返回所有被测试抽象类的具体子类实例,第二类定义抽象方法返回所有被测试抽象类的具体子类行为期望值。如下面代码,
Commodity
类是一个商品抽象类,该类的抽象方法描述具体如下:
getCommodityName():
取商品名称
changerName():
修改商品名称
getCommodityPrice():
取商品价格
changerPrice():
修改商品价格
Commodity
类具体代码如下
package
com.fastpiont;
public
abstract
class
Commodity {
public
abstract
String getCommodityName();//
取得商品名称
public
abstract
void
changerName(String newName);//
修改商品名称
public
abstract
double
getCommodityPrice();//
取得商品价格
public
abstract
void
changerPrice(
double
newPrice);//
修改商品价格
CommodityTestCase
是
Commodity
抽象类的测试类,同样该类被声明为抽象的。
Commodity
抽象类包含了
getCommodity()
工厂方法返回具体类实例,因为这才是真正的被测试对象。
PrepareAndGetExpectedName()
、
PrepareAndGetExpectedPrice()
、
PrepareAndChangerExpectedName()
、
PrepareAndChangerExpectedPrice()
四组方法分别返回具体类实例行为的期望值,即该实例行为的判断基准,具体代码如下:
package
com.fastpiont;
import
static
org.junit.Assert.*;
import
org.junit.After;
import
org.junit.Before;
import
org.junit.Test;
public
abstract
class
CommodityTest {
Commodity comm;
public
abstract
Commodity getCommodity();//
工厂方法,返回具体商品类
public
abstract
String prepareAndGetExpectedName();//
返回期望值
public
abstract
double
prepareAndGetExpectedPrice();
public
abstract
String repareAndChangerExpectedName();//
返回更改期望值
public
abstract
double
prepareAndChangerExpectedPrice
();
@Before
public
void
setUp()
throws
Exception {
comm = getCommodity();
@After
public
void
tearDown()
throws
Exception {
@Test
public
void
testGetCommodityName() {
String expected = prepareAndGetExpectedName();
String received = getCommodity().getCommodityName();
assertEquals
(expected, received);
@Test
public
void
testChangerName() {
comm.changerName(repareAndChangerExpectedName());
assertEquals
(repareAndChangerExpectedName(), comm.getCommodityName());
@Test
public
void
testGetCommodityPrice() {
double
expected = prepareAndGetExpectedPrice();
double
received = getCommodity().getCommodityPrice();
assertEquals
(expected, received);
@Test
public
void
testChangerPrice() {
comm.changerPrice(
prepareAndChangerExpectedPrice
());
assertEquals
(
prepareAndChangerExpectedPrice
(), comm.getCommodityPrice());
现在根据抽象类测试思想构造一个集成了
Commodity
抽象类的具体商品子类
Commodity_Book
,
Commodity_Book
类的构造方法有两个传参,即根据传入的书籍名称值和书籍单价值生成一本书实例。
Commodity_Book
类不鼓励直接修改书籍的属性,但是可以通过连歌公共方法
changerName()
和
changerPrice()
来实现,具体代码如下:
package
com.fastpiont;
public
class
Commodity_Book
extends
Commodity {
private
String book_name;
private
double
book_price;
public
Commodity_Book(String bookname,
double
bookprice) {
book_name = bookname;
book_price = bookprice;
public
void
changerName(String newName) {
setBook_name(newName);
public
void
changerPrice(
double
newPrice) {
setBook_price(newPrice);
public
String
getBook_name() {
return
book_name;
private
void
setBook_name(String book_name) {
this
.book_name = book_name;
public
double
getBook_price() {
return
book_price;
private
void
setBook_price(
double
book_price) {
this
.book_price = book_price;
@Override
public
String getCommodityName() {
//
TODO
Auto-generated method stub
return
getBook_name();
@Override
public
double
getCommodityPrice() {
//
TODO
Auto-generated method stub
return
getBook_price();
Commodity_BookTestCase
类继承了
CommodityTestCase
抽象类,整个类显得非常简单,包括工厂方法返回一个具体的
Commodity
实例和四个针对该实例的期望值设定,具体代码如下:
package com.fastpiont;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
public abstract class CommodityTest {
Commodity comm;
public abstract Commodity getCommodity();//
工厂方法,返回具体商品类
public abstract String prepareAndGetExpectedName();//
返回期望值
public abstract double prepareAndGetExpectedPrice();
public abstract String repareAndChangerExpectedName();//
返回更改期望值
public abstract double prepareAndChangerExpectedPrice();
@Before
public void setUp() throws Exception {
comm = getCommodity();
@After
public void tearDown() throws Exception {
@Test
public void testGetCommodityName() {
String expected = prepareAndGetExpectedName();
String received = comm.getCommodityName();
assertEquals(expected, received);
@Test
public void testChangerName() {
comm.changerName(repareAndChangerExpectedName());
assertEquals(repareAndChangerExpectedName(), comm.getCommodityName());
@Test
public void testGetCommodityPrice() {
double expected = prepareAndGetExpectedPrice();
double received = comm.getCommodityPrice();
assertEquals(expected, received, 0.001);
@Test
public void testChangerPrice() {
comm.changerPrice(prepareAndChangerExpectedPrice());
assertEquals(prepareAndChangerExpectedPrice(),
comm.getCommodityPrice(), 0.001);
这种针对抽象类的测试方法是
Junit
推导者所主张的,好处在于该抽象类的所有具体子类都不用在测试抽象类中的所有抽象发发(抽象类中的具体方法除外,因为该方法可能被具体子类覆盖),符合
XP
测试的接口测试定义。
专注于自动化、性能研究,博客为原创,转载请注明文章来源于:http://www.cnblogs.com/Automation_software/ 只求在IT界有一个清闲的世界让我静心的去专研,不求功名利禄,只为心中的那份成就感及自我成长、自我实现的快感。