技术开发 频道

使用JsUnit和JSMock的JavaScript测试驱动开发

  一个赢钱的场景测试

  我们可以用学到的任何知识测试下面的场景。这个测试模拟了一个用户在老虎机上先输后赢的情形。

  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;

  };

  最后,这是一个可以运行的老虎机的示例:

<html>
<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)。他是一个作家和演讲家,是开源社区的活跃分子。

0
相关文章