Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Sinon to mock a constant/variable?

Tags:

I'm fairly new to testing and even newer to Sinon.

Here I have an express route set up:

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));
}

My aim is to test that the post call to / runs appropriately. My test script is:

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

Though my test passes it returns status: 500 due to the const ctx = context() not being recognized. Is there an appropriate/correct way to spy on the variable ctx and return a mock variable within my test using Sinon? I've been spinning my wheels here for so long.

like image 738
Iqen Avatar asked Mar 05 '17 01:03

Iqen


People also ask

How do you mock a function in Sinon?

You must call mock() on an object. To complete the test, you must call the verify() function to check that all the mock's expectations were met.

How do I stub an object in Sinon?

If you need to check that a certain value is set before a function is called, you can use the third parameter of stub to insert an assertion into the stub: var object = { }; var expectedValue = 'something'; var func = sinon. stub(example, 'func', function() { assert. equal(object.

How do you mock a variable in mocha?

var sinon = require('sinon'); var start_end = require('./start_end'); describe("start_end", function(){ before(function () { cb_spy = sinon. spy(); }); afterEach(function () { cb_spy. reset(); }); it("start_pool()", function(done){ // how to make timer variable < 1, so that if(timer < 1) will meet start_end.

What is Sinon Spy ()?

sinon.spy(object, "property", ["get", "set"]) creates spies that wrap the getters and setters for object.property . The spies will behave exactly like the original getters and setters, but you will have access to data about all calls. Example: var object = { get test() { return this.


1 Answers

This is a common problem which I've come accross myself. I've tested multiple solutions, the one I've found to work best is Mockery.

It works like this: before you require your module under test, you tell Mockery to substitute modules the module under test requires with mocks.

For your code, it would look something like this:

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();
    });
});
like image 191
Patrick Hund Avatar answered Sep 25 '22 10:09

Patrick Hund