单元测试实践小结1

来源:互联网 发布:自动化软件开发 编辑:程序博客网 时间:2024/05/19 09:17
在系统开发过程种使用单元测试,会带来很多的的好处,最明显为:
When you become convinced of the value of comprehensive unit testing, you’ll find that it begins to influence how you write code, and the frameworks you choose to use。

应用单元测试,首先要解决的是单元测试的关注点。
测试的关注点在于测试逻辑,只要有逻辑就要写测试代码。测试的手段就是验证所有被测试方法的所有产出物,包括:
1. 测试方法的返回值
2. 测试方法的执行流程
例如:
public class DomainService {private static TheDAO dao = new TheDAO ();public ReturnObject findByCond(String) {return (ReturnObject)dao.getBeanByCondition("select * from ReturnObject
where cond=
"+ paramter, ReturnObject.class);}}
在对于测试findByCond方法,有两个测试用例:
A.测传递给TheDAO.getBeanByCondition的参数的正确性,如果参数不是”select * from ReturnObject where cond=?”和ReturnObject.class则返回为null。
B.测返回的对象正确性。

    特别是第二点,在商业应用上比较常见的。通常有些方法无明显output,通常是执行写表操作的。对于这样的方法就是测试它的执行流程。当然这些方法本身包含逻辑的。

    一个简单的解决方法是利用Access Log来实现(虽然这样的测试不多,而写的case代码也看着怪怪的)。
public class ServiceExample{private DatabaseDao1 dao1;private DatabaseDao2 dao2;public void noOutputMethod(){if(...)dao1.update(...);if(...)dao2.delete();}}
相关的测试代码可以这样:
public class MockDatabaseDao1 implements DatabaseDao1 {private Map map;public void setMap(Map map){this.map = map;}public void update(args){map.put("MockDatabaseDao1.update", args);}}public class MockDatabaseDao2 implements DatabaseDao2 {private Map map;public void setMap(Map map){this.map = map;}public void delete(args){map.put("MockDatabaseDao2.delete", args);}}public class ServiceExampleTestCase{private Map map = new HashMap();public void testNoOutputMethod(){DaoTest test = new DaoTest();DatabaseDao1 dao1 = new MockDatabaseDao1();dao1.setMap(map);dao2.setMap(map);DatabaseDao2 dao2 = new MockDatabaseDao2();test.setDao1(dao1);test.setDao2(dao2);test.noOutputMethod();assertEquals(new Boolean(true), new Boolean(map.containsKey("MockDatabaseDao1.update")));assertEquals(new Boolean(true), new Boolean(map.containsKey("MockDatabaseDao2.delete")));}}

例子只测试执行流程,实际实践中还可以验证所有的参数。
我们还可以考虑利用AOP来改进这个测试方法。then, we needn't to do the same work,each time. We repeat it only once.