EI-01
EI-01

Reputation: 1095

res.status(...).json is not a function when running test with mocha, sinon and chai

Hello i'm running into a failing unit test for a controller. I mocked the response object and but the test keeps failing due to json is not a function and also the test fails due to statusCode being undefined and its expected to be 200.

exports.getAllPrograms = async (req, res) => {
    try {
        let programs = [];
        const result = await Program.fetchAll();
        result.rows.forEach(item => {
            programs.push(new Program(item.id, item.name, item.description))
        });
        res.status(200).json(programs);
        
    } catch(err) {
        if (!err.statusCode) {
            err.statusCode = 500;
        }
        console.log(err);
    }
}

And my unit test:

it('', async () => {
     sinon.stub(Program, 'fetchAll')
     Program.fetchAll.returns(Promise.resolve({rows:[{id:1, name:"John", description:"Having a bad day with testing"}]}))
     const res = {
         send: function(){},
         json: (d) => {
            console.log("\n : " + d);;
         },
         status: (s) => {
             this.statusCode = s;
             return this;
         }
     };

     await ProgramController.getAllPrograms({}, res);
     expect(res.statusCode).to.equal(200);
     Program.fetchAll.restore();
 })

Error message when attempting to run the test:

TypeError: res.status(...).json is not a function
    at Object.exports.getAllPrograms (/Users/Documents/scratch/controllers/program.js:10:25)
    at async Context.<anonymous> (/Users/Documents/scratch/test/controller-test.js:21:6) {
  statusCode: 500
}

  0 passing (9ms)
  1 failing

  1) :
     AssertionError: expected undefined to equal 200
      at Context.<anonymous> (test/controller-test.js:23:32)

Upvotes: 1

Views: 5316

Answers (2)

Rohit Parte
Rohit Parte

Reputation: 4026

For response body, we can do like

let res = {
    status: (function (status) {
        this.status = status
        return this;
    }),
    json: function (body) {
        this.body = body
        return this;
    },
}

await api(req, res)
expect(res.status).toBe(200)
expect(res).toHaveProperty('body')
expect(res.body).toBeTruthy()

Upvotes: 0

EI-01
EI-01

Reputation: 1095

Hah i figured the problem. When creating the mock object i should have avoided the use of arrow functions. Basically replace arrow functions with function expressions.

const res = {
         send: function(){},
         json: (d) => {
            console.log("\n : " + d);;
         },
         status: (s) => {
             this.statusCode = s;
             return this;
         }
     };

with

const res = {
         send: function(){},
         json: function(d) {
            console.log("\n : " + d);;
         },
         status: function(s) {
             this.statusCode = s;
             return this;
         }
     };

Upvotes: 7

Related Questions