使用Sinon模拟一个常量/变量?

5

我对测试比较陌生,对Sinon更是新手。

这里有一个Express路由设置:

import context = require("aws-lambda-mock-context");

this.router.post('/', this.entryPoint);

public entryPoint(req: Request, res: Response, next: NextFunction) {
    const ctx = context();
    alexaService.execute(req.body, ctx);
    ctx.Promise
        .then((resp: Response) => res.status(200).json(resp))
        .catch((err: Error) => res.status(500));
}

我的目标是测试对/的post调用是否适当运行。我的测试脚本如下:

describe('/POST /', () => {
    it('should post', () => {
        chai.request(app)
            .post('/v2')
            .end((err, res) => {
                expect(res).to.be.ok;
            });
    });
});

尽管我的测试通过了,但由于未能识别const ctx = context()导致返回status: 500。在使用Sinon时,是否有适当/正确的方法来监视变量ctx并在我的测试中返回模拟变量?我一直在这里挣扎了很长时间。

1个回答

4
这是一个常见的问题,我自己也遇到过。我尝试了多个解决方案,发现Mockery效果最好。
它的工作原理是:在要求测试模块之前,您告诉Mockery用模拟替换测试模块所需的模块。
对于您的代码,它看起来应该像这样:
const mockery = require('mockery');
const { spy } = require('sinon');

describe('/POST /', () => {
    let ctxSpy;
    beforeEach(() => {
        mockery.enable({
            useCleanCache: true,
            warnOnUnregistered: false
        });
        ctxSpy = spy();
        mockery.registerMock('"aws-lambda-mock-context"', ctxSpy);

        // change this to require the module under test
        const myRouterModule = require('my-router-module'); 

        myRouterModule.entryPoint({}, {}, () => {});
        return ctxSpy;
    });

    it('should call ctx', () => {
        expect(ctxSpy).called.to.be.ok;
    });

    afterEach(() => {
        mockery.deregisterAll();
        mockery.disable();
    });
});

我知道这是老方法,但我建议在要求测试模块之前使用mockery.registerAllowable :) - Philippe Hebert
好的,我忘了提到这一点,因为我已经将它隐藏在我的设置中了。 - Patrick Hund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接