一个赢钱的场景测试
我们可以用学到的任何知识测试下面的场景。这个测试模拟了一个用户在老虎机上先输后赢的情形。
function testLoseThenWin(){
var buttonStub = {};
var balanceStub = {};
var reelsStub = [{},{},{}];
// a losing combination, followed by a winning combination
var randomNumbers = [2, 1, 3].concat([4, 4, 4]);
var randomStub = function(){return randomNumbers.shift();};
var slotMachine = new drw.SlotMachine(buttonStub, balanceStub, reelsStub,
randomStub);
var balance = 10;
slotMachine.deposit({responseText: String(balance)});
slotMachine.play();
assertEquals(balance - 1, balanceStub.innerHTML);
assertEquals('Sorry, try again', buttonStub.value);
slotMachine.play();
assertEquals('balance - 2 + 40', 48, balanceStub.innerHTML);
assertEquals('You Won!', buttonStub.value);
assertEquals('images/4.jpg', reelsStub[0].src);
assertEquals('images/4.jpg', reelsStub[1].src);
assertEquals('images/4.jpg', reelsStub[2].src);
}
drw.SlotMachine类的play方法实现是这样的:
drw.SlotMachine.prototype.play = function(){
var outcomes = [];
var msg = 'Sorry, try again';
for(var i = 0; i < this.reels.length; i++){
this.reels[i].src = 'images/' + (outcomes[i] = this.random()) + '.jpg';
}
if(outcomes[0] == outcomes[1] && outcomes[0] == outcomes[2]){
msg = 'You Won!';
this.balance += (outcomes[0] * 10);
}
this.buttonElement.value = msg;
this.balanceElement.innerHTML = --this.balance;
};

最后,这是一个可以运行的老虎机的示例:
<title>A Slot Machine Demonstration</title>
<head>
<script type='text/javascript' src='functional.js'></script>
<script type='text/javascript' src='slot_machine.js'></script>
<script type='text/javascript' src='network_client.js'></script>
<script type='text/javascript'>
window.onload = function(){
var leftReel = document.getElementById('leftReel');
var middleReel = document.getElementById('middleReel');
var rightReel = document.getElementById('rightReel');
var random = function(){
return Math.floor(Math.random()*5) + 1; // generate 1 through 5
};
slotMachine = new drw.SlotMachine(document.getElementById('buttonElement'),
document.getElementById('balanceElement'),
[leftReel, middleReel, rightReel],
random,
new NetworkClient());
slotMachine.render();
slotMachine.getBalance();
};
</script>
</head>
<body id='body'>
<div style="text-align:center; background-color:#BFE4FF; padding: 5px; width: 160px;">
<div>Slot Machine Widget</div>
<div style="padding: 5 0 5 0;">
<img id='leftReel'/>
<img id='middleReel'/>
<img id='rightReel'/>
</div>
<div>Balance: <span id="balanceElement"></span></div>
<input id="buttonElement" style="width:150px" type="button" onclick="slotMachine.play()"></input>
</div>
</body>
</html>
参考资料
* JSMock,一个用于JavaScript的具有完备功能的Mock对象库,作者是Justin DeWind
* JsUnit,一个用于客户端(浏览器内)JavaScript的单元测试框架
* Mocks Aren’t Stubs,Martin Fowler的一篇文章
* Functional是一个用于JavaScript的功能程序类库,作者是Oliver Steele
* Dependency Injection,Martin Fowler的一篇文章
作者简介
Dennis Byrne住在芝加哥,在DRW Trading工作,这是一个证卷交易公司(proprietary trading firm)和做市商(market maker)。他是一个作家和演讲家,是开源社区的活跃分子。