简体   繁体   English

间谍无法使用Mocha和Sinon跟踪异步功能测试

[英]Spy could not track on Async function test with Mocha and Sinon

I have isMember function as below; 我有isMember功能如下;

function isMember(req, res, next) {
MyService.GetUserAsync(authCookie)
        .then(function (user) {
            next();
        })
        .catch(function (err) {
            if (err.status === 400) {
                return res.redirect("/notAllowed");
            }
            else {
                return next(err);
            }
        });
}

My test is like below; 我的测试如下;

 beforeEach(function () {        
            // Overwrite the global timer functions (setTimeout, setInterval) with Sinon fakes
            this.clock = sinon.useFakeTimers();
        });
        afterEach(function () {
            // Restore the global timer functions to their native implementations
            this.clock.restore();
        });

 it.only("pass authentication and set authCookie", function (done) {
            var user = {
                userNameField: "fakeUserName"
            };
            sinon.stub(MyService, "GetUserAsync").returns(Promise.resolve(user));            
            var spyCallback = sinon.spy();
            var req {};
            var res = {};
            isMember(req, res, spyCallback);
            // Not waiting here!
            this.clock.tick(1510);
            // spyCallback.called is always false
            expect(spyCallback.called).to.equal(true);           
            done();
        });

For some reason this.clock.tick is not working and spyCallback.called is always false. 由于某种原因, this.clock.tick无法正常工作, spyCallback.called始终为false。 How can I achieve that my spy will wait until next() is called in isMember function? 我怎样才能实现我的间谍会等到isMember函数调用next()

The sinon fakeTimers replace the global setTimeout function, but your code does not contain any timeout function. sinon fakeTimers替换了全局的setTimeout函数,但是你的代码不包含任何超时函数。

You can use a setTimeout function to delay the execution of the expectation and then resolve your test by calling done() inside the setTimeout. 您可以使用setTimeout函数来延迟期望的执行,然后通过调用setTimeout中的done()来解决您的测试。 You can try something like this: 你可以尝试这样的事情:

setTimeout(function () {
  expect(spyCallback.called).to.equal(true);
  done();
}, 0);

You need to put done() inside a callback, because of how the event loop works in javascript. 你需要在回调中放置done() ,因为事件循环在javascript中是如何工作的。 First all synchronous code gets executed and then all pending async tasks are executed. 首先执行所有同步代码,然后执行所有挂起的异步任务。

Mocha has support for promises. 摩卡支持承诺。 If you return a promise from it() , it will be waited. 如果你从it()返回一个承诺,它将被等待。 So, you can do something like 所以,你可以做点什么

it.only("pass authentication and set authCookie", function (done) {
    var user = {
        userNameField: "fakeUserName"
    };
    sinon.stub(MyService, "GetUserAsync").returns(Promise.resolve(user));            
    var spyCallback = sinon.spy();
    var req {};
    var res = {};
    return isMember(req, res, spyCallback).then(function () {
        expect(spyCallback.called).to.equal(true); 
    });   
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM