Mock object孤立测试初步

本文介绍了一种使用Mock对象进行单元测试的方法,通过创建MockAccountManager替代真实的AccountManager,实现了对AccountService中transfer方法的隔离测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常开发人员不会是专门的测试人员,因此我写出来的一些测试案例也是粗粒度的测试,而这种测试一旦重构引入了一个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实现的)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值