7

I'm pretty new to node and this is my first time unit testing an app. I'm doing well with Jest faking the request with Jest function as below

// Create a fake request
 const mockRequest = (sessionData, body) => ({
  session: { data: sessionData },
  body
});

// Create a fake response
 const mockResponse = () => {
  const res = {};
  res.status = jest.fn().mockReturnValue(res);
  res.json = jest.fn().mockReturnValue(res);
  return res;
};

const mockNext = () => {
  const next = jest.fn();
  return next;
};

So I can use them like follows

doSomething(req, res, next);
expect(res.status).toHaveBeenCalledWith(201);
//or
expect(next).toHaveBeenCalled();

That's enough for all the cases until I found that my authorisation middleware includes a couple of parameters so I can not pass the fake res and req as below

exports.isAllowedTo = (par1, par2) => {
    return async (req, res, next) => {
        try {
            //
            // Grant logic here that needs par1 and par2
            //

            if(granted)
                next();
            else
                return res.status(401).json({
                    error: "You don't have enough permission to perform this action"
                });

        } catch (err) {
            res.status(406).json({
                error: err.toString(),
            })
        }
    }
}

If I test isAllowTo(req, res, next) with the mock req, res and next then I'm missing the 2 parameters needed by the function. Actually when I do this, the function isAllowTo() is not even called. I don't know how to deal with that. Any suggestion or approach?

Nathan Lo Sabe
  • 197
  • 1
  • 13

2 Answers2

3

Two months later I realized that the real problem is that I'm testing a function inside of another function. So firstly I store the function in a variable so I can test it as a regular middleware.

test('Grant access if user role is allowed to', async () => {

    const isAllowToTester = userController.isAllowedTo(par1, par2);

    await isAllowToTester(req, res, next)

    expect(next).toHaveBeenCalled();

});

Hope this helps someone else. Credits to this post

Nathan Lo Sabe
  • 197
  • 1
  • 13
0

Check out https://github.com/nock/nock it's a library dedicated to mocking requests and responses, it's really easy to use with unit tests/jest. I personally don't think is worth it to write your own mocking implementation.

noone
  • 21
  • 3
  • Thank you! Looks pretty useful mocking. AFAICS Nock calls the endpoint but I want to test unit by unit. The piece of code above is a middleware that I isolated in order to test it. – Nathan Lo Sabe Jan 31 '20 at 16:24
  • 1
    Hmm, I see, I think sinon's stubs could help you do that: https://sinonjs.org/releases/latest/stubs/ take a look. – noone Jan 31 '20 at 17:19