使用Mocha,Chai和Sinon测试延迟行动

时间:2015-08-11 20:39:04

标签: unit-testing mocha chai

我想为异步进程创建一个单元测试。我创建了一个简单的模拟情况,使用超时来延迟警报。 (真正的过程是动态加载JS文件)。

我刚开始与Mocha,Chai和Sinon合作。我在HTML文件旁边创建了一个名为vendor的文件夹。它包含最新版本的mocha.css,mocha.js,chai.js和sinon.js。

如果我注释掉setTimeout()来电,下面的代码就可以了。我应该如何更改它以便sinon.assert...调用将等待延迟操作发生?

<!DOCTYPE html>
<head>
  <title>Delayed alert test</title>
</head>

<body>
<div id="mocha"><p><a href=".">Index</a></p></div>
<div id="messages"></div>
<div id="fixtures"></div>
<link rel="stylesheet" type="text/css" href="vendor/mocha.css" />
<script src="vendor/mocha.js"></script>
<script src="vendor/chai.js"></script>
<script src="vendor/sinon.js"></script>

<script>
mocha.setup('bdd')

var spy = sinon.spy(window, 'alert')

describe("Test", function() {
  describe("#alert", function() {
    it("should show an alert", function(done) {
      this.timeout(5000)

      setTimeout(function () { // Works if these 2 lines...
        alert ("Once")
        alert ("Twice")
      }, 2000)                 // are commented out
      sinon.assert.called(spy)
      sinon.assert.calledTwice(spy)
      sinon.assert.calledWithExactly(spy, "Once")
      sinon.assert.calledWithExactly(spy, "Twice")
      done()
    });
  });
})

mocha.run();
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

一旦设置超时,就会调用你的断言和done()(如果测试到达那里)。

测试设置超时

this.timeout(5000)

安排您的测试在2秒内运行,然后立即继续。

setTimeout(...

检查失败的断言

sinon.assert.called(spy)

然后在setTimeout有机会跑之前退出。

断言需要在setTimeout完成后运行,并且因为我们在浏览器中,需要在try / catch块中捕获异步断言,因此实际异常可以通过done()传递回mocha

大多数异步API允许您传递&#34;回调&#34;函数in,在异步任务完成后调用,通常是你把断言/完成的函数。

在你的情况下,它更像是字面意思......

describe("Test", function() {
  describe("#alert", function() {
    it("should show an alert", function(done) {
      this.timeout(5000)

      var stub = sinon.stub(window, 'alert')

      var assertion = function(){
        try {
            sinon.assert.called(stub)
            sinon.assert.calledTwice(stub)
            sinon.assert.calledWithExactly(stub, "Oce")
            sinon.assert.calledWithExactly(stub, "Twice")
            done()
        } catch ( e ) {
            done( e )
        }
      }

      setTimeout(function () {
        alert ("Once")
        alert ("Twice")
        assertion()
      }, 2000)

    });
  });
})

https://jsfiddle.net/6w4p7rxz/

注意,我将spy更改为stub,以减少点击次数。还可以使用chai!也许sinon-chai也可以让事情更容易阅读。