问题:
setter方法怎么简单,
测试它是不是浪费时间呢?而且价值也不大!
情景:
JUnit新手常常问的问题是:“这个set方法是否应该测呢”其实如果你谨慎认为测试是来预防错误的,那么你想这个虽然简单但是也是可能出现错误的话,就应该测试。
方法:
最常见的set方法是在JavaBean中,bean对象有点像一个数据包:它包装了一堆数据,这些数据对外可读可写。例如:
Java代码 复制代码
1. public void testSetProperty(){
2. Bean bean = new Bean();
3. bean.setProperty(newPropertyVale);
4. assertEquals(newPropertyValue, bean.getProperty());
5. }
public void testSetProperty(){
Bean bean = new Bean();
bean.setProperty(newPropertyVale);
assertEquals(newPropertyValue, bean.getProperty());
}
描述步骤:
1. 将Property改为你要测试的bean属性值名称。
2. 创建一个类的实例
3. 如果newPropertyValue是复杂类型,比如另外一个JavaBean的索引,就想要地初始化newPropertyVale
4. 如果property是一个比字符串更复杂的对象,那么你要保证property所属的类的equals方法已经被恰当地实现。
讨论:
如果你没有相应的get方法,并且不愿仅仅为了测试set方法而添加它,那么你需要找出set方法的可观测的点,并且验证它。
另外一种常见的set方法应用是在Command设计模式中。如果命令被提交给命令解释器以获得执行,那么命令应该有一个相应的get方法:否则的话,命令解决器如何获取输入的参数呢?另外,如果命令遵从“行为”模式(也就是说提供自己的执行方法),那么命令本身就能完全包括输入的参数,这样就没办法直接验证set方法的行为了。这种情况下,就必须执行该命令并分析,以验证输入的参数是否正确地被set方法使用。
看个简单的例子:(该例子主要是执行银行转账行为类。)
Java代码 复制代码
1. public class BankTransferAction{
2. private String sourceAccountId;
3. private String targetAccountId;
4. private Money amount;
5.
6. public void setAmount(Money amount){
7. this.amount = amount;
8. }
9.
10. public void setSourceAccountId(String sourceAccountId){
11. this.sourceAccountId = sourceAccountId;
12. }
13.
14. public void setTargetAccountId(String targetAccountId){
15. this.targetAccountId = targetAccountId;
16. }
17.
18. public void execute(){
19. Bank bank = Bank.getInstance();
20. bank.transfer(sourceAccountId, targetAccountId, amount);
21. }
22. }
public class BankTransferAction{
private String sourceAccountId;
private String targetAccountId;
private Money amount;
public void setAmount(Money amount){
this.amount = amount;
}
public void setSourceAccountId(String sourceAccountId){
this.sourceAccountId = sourceAccountId;
}
public void setTargetAccountId(String targetAccountId){
this.targetAccountId = targetAccountId;
}
public void execute(){
Bank bank = Bank.getInstance();
bank.transfer(sourceAccountId, targetAccountId, amount);
}
}
虽然这个实现中的方法都很简单,但我们不得不使用 execute()方法来测试各种set方法,因为我们没有
其他可以观测的点。
注意这个实现严格遵循了execute()方法的规范:不接受任何参数。一般来讲,程序员执行这个方法是为了让超类或者接口执行当前的execute()方法。因为这个动作自己获取参数并自动执行,因此我们也不清楚,按照这个规范进行设计到底带来了声明好处。为了验证这个类的方法,我们将提交我们自己的 Bank类,以验证传递给transfer方法的参数。这种办法仅有的问题是我们提交的严格“假”银行对象,而不是严格产品代码中真正使用的银行对象。可以选择一个新的execute()方法,并在bank类中公用一个setInstance方法供我们自由提交bank对象。
例如:
Java代码 复制代码
1. public class BankTransferAction{
2. private String sourceAccountId;
3. private String targetAccountId;
4. private Money amount;
5.
6. public void setAmount(Money amount){
7. this.amount = amount;
8. }
9.
10. public void setSourceAccountId(String sourceAccountId){
11. this.sourceAccountId sourceAccountId;
12. }
13.
14. public void setTargetAccountId(String targetAccountId){
15. this.targetAccountId = targetAccountId;
16. }
17.
18. public void execute(){
19. execute(Bank.getInstance());
20. }
21.
22. public void execute(Bank bank){
23. bank.transfer(sourceAccoutId, targetAccountId, amount);
24. }
25. }
public class BankTransferAction{
private String sourceAccountId;
private String targetAccountId;
private Money amount;
public void setAmount(Money amount){
this.amount = amount;
}
public void setSourceAccountId(String sourceAccountId){
this.sourceAccountId sourceAccountId;
}
public void setTargetAccountId(String targetAccountId){
this.targetAccountId = targetAccountId;
}
public void execute(){
execute(Bank.getInstance());
}
public void execute(Bank bank){
bank.transfer(sourceAccoutId, targetAccountId, amount);
}
}
测试代码
Java代码 复制代码
1. public class BankTransferActionTest extends TestCase{
2.
3. public void testSettingInputParameters(){
4. BankTransferAction action = new BankTransferAction();
5. action.setSourceAccountId("source");
6. action.setTargetAccountId("target");
7. action.setAmount(Money.dollars(100));
8. action.execute(new Bank(){
9. public void transfer (String sourceAccountId, String targetAccountId, Money amount){
10. assertEquals("source", sourceAccountId);
11. assertEquals("target",targetAccounntId);
12. assertEquals(Money.dollars(100), amount);
13. }
14. });
15. }
16.
17. }