JS测试中间件将返回next()

时间:2018-10-25 02:17:39

标签: javascript unit-testing middleware sinon restify

我有一个像这样的中间件类

// code.js
function validation(req, res, next) {
    if (validationLogic(req)) {
        res.send(400);
        return next(false);
    }
    return next();
}

// code.test.js
describe('validation', () => {
    describe('when req is valid', () => {
        //setting up req, res, next stub

        //some other test

        //HERE IS MY QUESTION, how do I text that validation returns next(), and not next(false)
        it('return next(), and next() is called exactly once', () => {
            const spy = sinon.spy();
            nextStub = spy;
            const result = validation(reqStub, resStub, nextStub);
            assert(spy.calledOnceWithExactly());
            assert(result === nextStub()); // both of this
            assert(result === nextStub(false)); // and this line passed
        });
    });
});

我试图测试我的validation函数是否返回next()而不是next(false)。但是在测试中,看起来只有assert(spy.calledOnceWithExactly())可以测试next中的参数。但是,assert(result === nextStub())之后的那一行不能测试任何东西,除了结果实际上来自功能next()

assert(spy.calledOnceWithExactly())是否足够,还是还有另一种测试方法?

2 个答案:

答案 0 :(得分:0)

您不需要使用间谍。您总是可以创建一个“占位符”函数来接受参数并将其替换为next,并确保该函数未返回false

it('return next(), and next() is called exactly once', () => {
    const nextStub = (arg) => (arg === false ? arg : 'I was called!');
    const result = validation(reqStub, resStub, nextStub);
    
    assert(result !== false);
    assert(result === 'I was called!');
});

类似的事情可能起作用。或者,如果您真的想使用间谍,则可以检查间谍的返回值和调用间谍的内容。确保您的间谍函数可以接受参数。

https://sinonjs.org/releases/v7.0.0/spy-call/

答案 1 :(得分:0)

一种干净的方法是使用expectation来验证一次next是否使用了确切的参数,并且结果是从validation返回的:

it('return next(), and next() is called exactly once', () => {
  const expectation = sinon.mock().once().withExactArgs().returns('called with no args');
  nextStub = expectation;
  const result = validation(reqStub, resStub, nextStub);
  expectation.verify();  // SUCCESS
  assert(result === 'called with no args');  // SUCCESS
});