单元测试的威力

来源:互联网 发布:锦衣卫同知 编辑:程序博客网 时间:2024/04/27 15:18

为一段代码补充单元测试后出现了让人郁闷的red bar和蓝色的Failures,这是一段中古时期的代码,读取.properties文件并返回Properties句柄:

  1. public class LoadProp {
  2.     /**
  3.      * 读取.properties配置文件,返回Properties
  4.      * @param path 文件路径
  5.      * @return Properties
  6.      */
  7.     public Properties getProp(String path) {
  8.         InputStream inStream = null;
  9.         
  10.         try {
  11.             inStream = getInStream(path);
  12.             Properties prop = new Properties();
  13.             prop.load(inStream);
  14.             inStream.close();
  15.             
  16.             return prop;
  17.         } catch (IOException e) {
  18.             e.printStackTrace();
  19.             return null;
  20.         } finally {
  21.             if(inStream != null) {
  22.                 try {
  23.                     inStream.close();
  24.                 } catch (IOException e) {
  25.                     // TODO Auto-generated catch block
  26.                     e.printStackTrace();
  27.                 }
  28.             }
  29.         }
  30.     }
  31.     
  32.     protected InputStream getInStream(String path) {
  33.         return this.getClass().getClassLoader().getResourceAsStream(path);
  34.     }
  35. }

当然,这段代码还有很大的改进余地,可以使用ICO和method factory进行重构,抛开其结构优劣不提,仅对功能进行测试,以下是单元测试代码:

1、MockInputStream

  1. public class MockInputStream  extends InputStream {
  2.     private int position = 0;
  3.     private int closeCount = 0;
  4.     private String buffer;
  5.     
  6.     public void setBuffer(String buffer) {
  7.         this.buffer = buffer;
  8.     }
  9.     
  10.     public int read() throws IOException {
  11.         if(position == this.buffer.length()) {
  12.             return -1;
  13.         }
  14.         
  15.         return this.buffer.charAt(position++);
  16.     }
  17.     
  18.     public void close() throws IOException {
  19.         this.closeCount++;
  20.         super.close();
  21.     }
  22.     
  23.     public void verify() throws AssertionFailedError {
  24.         if(closeCount != 1) {
  25.             throw new AssertionFailedError("close() should have been called once and once only!" +
  26.                     " This close is " + closeCount);
  27.         }
  28.     }
  29. }

2、TestTableLoadProp

  1. public class TestTableLoadProp extends LoadProp {
  2.     private InputStream inputStream;
  3.     public InputStream getInStream(String path) {
  4.         
  5.         return inputStream;
  6.     }
  7.     public void setInputStream(InputStream inputStream) {
  8.         this.inputStream = inputStream;
  9.     }
  10. }

3、TestLoadProp

  1. public class TestLoadProp extends TestCase {
  2.     private MockInputStream mockInputStream;
  3.     private TestTableLoadProp prop;
  4.     
  5.     public void setUp() {
  6.         mockInputStream = new MockInputStream();
  7.         mockInputStream.setBuffer("invoiceManager.roleId = 5862");
  8.         prop = new TestTableLoadProp();
  9.         prop.setInputStream(mockInputStream);
  10.     }
  11.     
  12.     public void testGetProp() {
  13.         this.assertNotNull(prop.getProp(Variable.FREEZETIME));
  14.     }
  15.     
  16.     public void tearDown() {
  17.         mockInputStream.verify();
  18.     }
  19. }

运行TestLoadProp将会提示测试失败:“close() should have been called once and once only! This close is 2”

问题再明显不过。

 

这个问题很隐蔽,而且并非人人都喜欢掘墓,挖出中古时期的代码,由此可见单元测试的威力。

 

原创粉丝点击