`

测试驱动开发 我的现金系统

    博客分类:
  • Java
阅读更多

本文以我的现金系统为例来介绍如何用测试驱动开发。

主要以货币汇率的不同转换来介绍。

FM:一美元=2法郎

1也就是说5美元+10法郎=10美元

这时候 我们需要列一个计划清单,来标识工作顺序。这样一个一个解决问题,工作在快速完成当中

我们要改变开发过程中首先建立对象的模式,不是先建立对象而是先建立测试。首先时间最简单的乘法。

public void testChengfa(){
		Dollar five = new Dollar(5);
		five.times(2);
		assertEquals(10,five.amount);
	}

 

为什么这么做,我们要知道 5美元*2=10美元,是为了响应上面的公式,我们要小步一步步实现。

package com.mixian.first_two;

public class Dollar {

	int amount;

	public Dollar(int amount) {
		this.amount = amount;
	}

	public void times(int time) {
		amount*=time;
		//amount = this.amount*time;
	}

}

 

一步一步实现 amount=10;amount=5*2; amount=amount*time;amount*=time;

 

2:与测试开发驱动相对的是体系结构驱动(为了获得整洁可用的代码)

我们对dollar操作的时候,这个对象变化了

增加新的测试
public void testChengfa(){
		Dollar five = new Dollar(5);
		five.times(2);
		assertEquals(10,five.amount);
		five.times(3);
		assertEquals(15,five.amount);
	}

 结果是junit.framework.AssertionFailedError: expected:<15> but was:<30>

 3:数值对象:就是可以将对象当做数值来用,要求数值对象的实例变量值在构造函数中被指定,以后在也不可以发生变化。好处两个五美元对象,不会因为一个对象而改变另一个对象,如果需要7美元就需要重新创建一个

4:测试相等性

public void testEquals(){
  assertTrue(new Dollar(5).equals(new Dollar(5)));
 }

public boolean equals(Object object){
  Dollar dollar = (Dollar)object;
  return amount==dollar.amount;
 }

5:让dollar对象之间进行比较

public void testChengfa(){
  Dollar five = new Dollar(5);
  /* 为什么不是10
  five.times(2);
  assertEquals(10,five.amount);
  */
  //如果我们从times返回一个新对象的时候,那么我就可以对原来的dollar对象进行操作
  //Dollar product = five.times(2);
  //assertEquals(10,product.amount);
  assertEquals(new Dollar(10),five.times(2));
  //product = five.times(3);
  //assertEquals(15,product.amount);
  assertEquals(new Dollar(15),five.times(3));
  //five.times(3);
  //assertEquals(15,five.amount);
 }

 

小结:以上已经完成了美元对象的乘法运算,以及对象之间的判等,下面要实现法郎的乘法与判等,才能为两个对象之间的混合操作打基础

 

1:package com.mixian.first_two;

public class Fancs {
 private int amount;
 
 Fancs(int amount){
  this.amount = amount;
 }
 
 public Fancs times(int time){
  return new Fancs(amount*time);
 }
 
 public boolean equals(Object object){
  Fancs fancs = (Fancs)object;
  return amount==fancs.amount;
 }
 
}
 法郎对象的操作 记得不要忘复写equals方法

2:现在的情况下 发现两个对象中有很多相同的类,所以我们要找出一个他们的父类。

 将变量上移,将equals 中的类替换成money

package com.mixian.first_two;

public class Dollar extends Money{

	//private int amount;

	public Dollar(int amount) {
		super.amount = amount;
		//System.out.println(this.amount);
	}

	public Dollar times(int time) {
		//amount*=time;
		//amount = this.amount*time;
		//System.out.println(amount*time);
		return new Dollar(amount*time);
	}
	
	public boolean equals(Object object){
		Money money = (Money)object;
		return amount==money.amount;
	}

}
package com.mixian.first_two;

public class Money {
	protected int amount;
}

 然后将equals方法移到Money类中

这时候增加断言

:assertFalse(new Dollar(5).equals(new Fancs(5)));

返现他们是相等的对象,这样问题就出来了,我们需要表示出两个对象的不同。

也就是说:要判断两个类的数值相等而且要是相同的类

amount==money.amount && getClass()==money.getClass();

测试通过成功了。

3:现在要动手出去times()方法,这样才可以统一计算

在Money类中引入一个返回dollar对象的工厂方法

Money four = Money.dollar(4);
  //assert(new Dollar(4).equals(four));
  assertEquals(new Dollar(10),four.times(2));
  assertEquals(new Dollar(15),four.times(3));
  

 

public abstract class Money {
 protected int amount;
 abstract Object times(int i) ;
 

因为在Money类中没有对times方法进行实现,所以可以将times方法定义为抽象的方法

 

4:更改测试,建立静态的方法

  assertEquals(Money.dollar(10),four.times(2));
  assertEquals(Money.dollar(15),four.times(3));

 
 static Money dollar(int amount){
  return new Dollar(amount);
 }

 static Money fancs(int amount){
  return new Fancs(amount);
 }

 

5:根据字符串的不同创建不同的方法

 

 

 

 

 

分享到:
评论
1 楼 金米线 2010-10-25  
感觉学习理解的不够深入,准备在重新学习一遍

相关推荐

Global site tag (gtag.js) - Google Analytics