Написание теста шутки для связанных функций в node.js

У меня есть функция, которую я хочу протестировать с помощью шутки, функция в основном выполняет некоторую проверку токенов и принимает 3 параметра

это код функции, которую я хочу протестировать:

const verifyToken = (req, res, next) => {
    // check header or url parameters or post parameters for token
    var token = req.headers['x-access-token']

    if (!token) return res.status(403).send({ auth: false, message: 'No token provided.' })

    // verifies secret and checks expire date
    jwt.verify(token, config.secret, (err, decoded) => {
        if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' })

        //put user inside req.user to use the user in other routes
        User.findById(decoded.id, (err, user) => {
            if (err) {
                return res.status(500).json({
                    message: err
                })
            } else if (!user) {
                return res.status(404).json({
                    message: 'No user found'
                })
            } else {
                req.user = user
            }
            next()
        })
    })
}

поэтому я пишу первый тест, который проверяет, не указан ли токен в запросе, что он отправляет 403 с сообщением. Ниже приводится тест.

const verifyToken = require('../../config/token')

describe('veryfiy token tests', () => {
    it('Should give 403 status when no token is present', () => {
        let mockReq = {
            headers: {}
        }
        var mockRes = {
            status: code => code
            send: message => message
        }

        let nextCalled = false

        let next = () => {
            nextCalled = true
        }

        expect(verifyToken(mockReq, mockRes, next)).toBe(403)
    })
})

Теперь тест проходит с ошибкой: TypeError: res.status (...). Send не является функцией

когда я удалил .send () из res.status в коде, тест прошел.

Я пытался выяснить, как имитировать как status (), так и send () в объекте res. но решения пока не нашел.

Tnx

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
2 045
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Думаю, проблема в том, что в результате res.status() не имеет функции под названием send().

Попробуйте использовать это:

  var mockRes = {
    status: code => ({
      send: message => ({code, message})
    }),
  };

Вы должны иметь возможность тестировать:

  var result = verifyToken(mockReq, mockRes, next);
  expect(result.code).toBeDefined();
  expect(result.code).toBe(403);

PS: Не тестировал код :)

Это сработало! я не знал, что мне нужно вложить функции. tnx для примера!

Gilles Vercammen 07.09.2018 15:21

вы можете создать цепочку фиктивных классов и тестов, независимо от того, выполняются ли функции или нет.

вот пример.

  class MockResponse {
    constructor() {
    this.res = {};
     }
     status = jest
     .fn()
     .mockReturnThis()
     .mockImplementationOnce((code) => {
       this.res.code = code;
      return this;
     });
    send = jest
    .fn()
    .mockReturnThis()
    .mockImplementationOnce((message) => {
      this.res.message = message;
      return this;
    });
    }

а теперь используйте этот фиктивный класс для тестирования. и проверьте, что данная функция выполнилась с заданным результатом или нет. пример как

  it("should not call next function, and return 401, if token has not been found", async () => {
      let res = new MockResponse(); // here i initialised instance of class
      let  next = jest.fn();
      let req = {cookies:""} // header or cookies where you are receiving token here in my case empty.
       await authentication(req, res, next); // here i used my mock res class
      expect(next).not.toHaveBeenCalled(); // you must check that next will not be called. 
      expect(res.status).toHaveBeenCalledWith(401);//you can check result of status
      expect(res.send).toHaveBeenCalledWith("not authenticated");// send() message in your function
    });

Другие вопросы по теме