zoukankan      html  css  js  c++  java
  • Junit实现抽象类测试(一)

            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);// 修改商品价格

    }

     CommodityTestCaseCommodity抽象类的测试类,同样该类被声明为抽象的。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_BookCommodity_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界有一个清闲的世界让我静心的去专研,不求功名利禄,只为心中的那份成就感及自我成长、自我实现的快感。
  • 相关阅读:
    list extend 和 append
    构建同元素的列表
    Python拷贝(深拷贝deepcopy与浅拷贝copy)
    MySQL之对数据库库表的字符集的更改
    Shell之while循环
    安装keepalived
    Zabbix监控MySQL
    Ganglia监控MySQL
    将Nagios监控信息存入Mysql
    Hadoop之回收站
  • 原文地址:https://www.cnblogs.com/Automation_software/p/1944393.html
Copyright © 2011-2022 走看看