通常开发人员不会是专门的测试人员,因此我写出来的一些测试案例也是粗粒度的测试,而这种测试一旦重构引入了一个BUG,就会有一系列的测试失败。
Mock object(简称mock)是用来代替与你的要测试的代码协作的对象。你的代码可以调用mock object的方法。
例子:
初步定义以下类或接口:
AccountService:提供有关账户的服务。
AccountManager:把数据持久化到数据库(例如JDBC)
Account:表示一个账户对象。
Account.java
public class Account {
private String accountId;
private long balance;
public long getBalance() {
return balance;
}
public Account(String accountId, long balance) {
super();
this.accountId = accountId;
this.balance = balance;
}
public void debit(long amount){
this.balance-=amount;
}
public void credit(long amount){
this.balance+=amount;
}
}
AccountManager接口:数据访问接口,管理Account对象的持久性和生命周期,给DAO层设计接口是比较常见和实用的设计方法,让所有的数据访问对象实现这个接口,遍于对DAO类的管理。
AccountMananger.java
public interface AccountMananger {
Account findAccountForUser(String userId);
void updateAccount(Account account);
}
Transfer方法用于在两个账户之间转帐,这里只使用到了DAO接口而没有真正访问数据库,这样的方法是容易隔离测试的。
AccountService.java
public class AccountService {
private AccountMananger accountManager;
public void setAccountManager(AccountMananger accountManager) {
this.accountManager = accountManager;
}
public void transfer(String senderID,String beneficiaryId,long amount){
Account sender = this.accountManager.findAccountForUser(senderID);
Account beneficiary = this.accountManager.findAccountForUser(beneficiaryId);
sender.debit(amount);
beneficiary.credit(amount);
this.accountManager.updateAccount(sender);
this.accountManager.updateAccount(beneficiary);
}
}
现在我希望能够对transfer方法进行测试,但是这里的AccountManager对象是需要访问数据库的对象,因此它与环境相关,因此用设计mock做为一个来空壳替换掉它来进行隔离测试。这样就可以对transfer方法进行孤立测试。
MockAccountManager.java
/**
* 用于隔离领域对象AccountManager
*/
public class MockAccountManager implements AccountMananger{
private Hashtable accounts = new Hashtable();
public void addAccount(String userId,Account account){
this.accounts.put(userId, account);
}
public Account findAccountForUser(String userId) {
return (Account)this.accounts.get(userId);
}
public void updateAccount(Account account) {
//do nothing
}
}
现在我们已经为编写transfer方法的单元测试做了准备。
TestAccountService.java
public class TestAccountService extends TestCase {
public TestAccountService(String name) {
super(name);
}
protected void setUp() throws Exception {
}
protected void tearDown() throws Exception {
}
public void testTransferOk(){
MockAccountManager mockAccountManager = new MockAccountManager();
Account sendAccount = new Account("1",200);
Account beneficiaryAccount = new Account("2",100);
mockAccountManager.addAccount("1", sendAccount);
mockAccountManager.addAccount("2", beneficiaryAccount);
AccountService accountService = new AccountService();
accountService.setAccountManager(mockAccountManager);//主要
accountService.transfer("1", "2", 50);
assertEquals(150,sendAccount.getBalance());
assertEquals(150,beneficiaryAccount.getBalance());
}
}
这时,已经成功隔离了另一个领域对象-AccountManager(真正的使用用是用JDBC实现的)
Mock object孤立测试初步
最新推荐文章于 2025-08-23 20:56:03 发布