Функция-заглушка не выполняется при выполнении теста с использованием sinon и mocha

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

приложение.js:

const express = require('express');
const { isValid } = require('./utils/index');

const config = require('./config.json')[process.env.NODE_ENV || 'development']


const app = express();

app.get('/', (req, res)=> {


    const url = config.url;
   try {
    const validUrl = isValid(url)
    .then(() => {
        return res.redirect(`https://${url}`);
    })
    .catch(() => {
        return res.status(400).send('Unable to redirect to the given url');
    })
   } catch(error) {
      return res.send('Internal Server Error') 
   }




})

const port = process.env.port || 3000;

const server = app.listen(port, ()=> {
    console.info('server listens on 127.0.0.1:3000');
})

module.exports = {server, app};

конфиг.json:

{
"development": {
    "url": "www.stackoverflow.com"
}, 
"test": {
    "url": "www.stackoverflow.com"
}

}

утилиты/index.js:

const http = require('http');


module.exports.isValid = (url) => {
    const options = {
        method: 'HEAD',
        host: url
    }
const promise = new Promise((resolve, reject) => {
    const req = http.request(options, () => {
        return resolve(true)
    })
    req.on('error', () => {
        return reject(new Error('Not valid'))
    })

    req.end();
})

return promise;
}

тест/index.js:

const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const index = require('../utils/index')
const { expect } = chai;

const { server } = require('../app');
const {url} = require('../config.json')['test'];



describe('isValid Test', () => {

    it('Should redirects an error when the url is not valid', async() => {

        const stub = sinon.stub(index, 'isValid');
        stub.withArgs(url).returns(Promise.reject(new Error('Not Valid')));
        const { status } = await request(server).get('/');

        expect(status).to.equal(400);

    })
})

Когда я выполняю тест, я получаю эту ошибку:

    (node:23622) UnhandledPromiseRejectionWarning: Error: Not Valid
    at Context.it (/home/hs/perso/mockTests/chaiMock/test/index.js:17:52)
    at callFn (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:387:21)
    at Test.Runnable.run (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:379:7)
    at Runner.runTest (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:535:10)
    at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:653:12
    at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:447:14)
    at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:457:7
    at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:362:14)
    at Immediate.<anonymous> (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:425:5)
    at runCallback (timers.js:705:18)
    at tryOnImmediate (timers.js:676:5)
    at processImmediate (timers.js:658:5)
(node:23622) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:23622) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
url:  www.stackoverflow.com
    1) Should redirects an error when the url is not valid


  0 passing (122ms)
  1 failing

  1) isValid Test
       Should redirects an error when the url is not valid:

      AssertionError: expected 302 to equal 400
      + expected - actual

      -302
      +400

      at Context.it (test/index.js:22:27)
      at process._tickCallback (internal/process/next_tick.js:68:7)
Поведение ключевого слова "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
1 005
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте проверить значение, которое вы отправляете на «хост» по вашему запросу, я полагаю, что вы нажимаете на «www.stackoverflow.com» и получаете http-код 400, поэтому вы получаете ошибку в своем тесте

Обычно, если URL-адрес действителен (в моем случае www.stackoverflow.com), API перенаправляет на страницу stackoverflow. В противном случае он возвращает ошибку. В моем тесте я хочу смоделировать результат, возвращаемый isValid в соответствии с заданным URL.

Slim 28.05.2019 15:16

Да, но вы Конечно параметр URL-адреса, который вы получаете в isValid (url), не является www.stackoverflow.com? Потому что вы не можете получить httpCode 400, если вы отправляете неверный URL-адрес

koFTT 28.05.2019 15:28

URL-адрес был www.stackoverflow.com, в process.env.development = developement API будет перенаправлять на страницу stackoverflow. Если только process.env.NODE_ENV= test заглушка не должна издеваться над ответом isValid. В моем тесте я хочу вернуть ошибку, тогда код состояния должен быть 400. В моем случае заглушка не вызывается. Она выполняется, но не вызывается при вызове request(app).get('/').

Slim 28.05.2019 15:35

Я понимаю, о чем вы говорите, но в файле config.json у вас один и тот же URL-адрес, настроенный как для разработки, так и для тестирования.

koFTT 28.05.2019 16:00
Ответ принят как подходящий

Проблема здесь в том, что ваш модуль приложения требуется и, в свою очередь, извлекает файл utils/index до того, как sinon заглушит интересующую вас функцию, я полагаю, что загрузчик модуля затем кэширует его, поэтому попытка sinon заглушить его не имеет никакого эффекта.

Чтобы убедиться, что ваш тест успешно пройден, вам нужно заглушить функцию isValid, прежде чем вам потребуется ваше приложение, т.е.

const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const { expect } = chai;

const index = require('../utils/index');

/* Stub here before the server is required */
const stub = sinon.stub(index, 'isValid');

const { server } = require('../app');
const { url } = require('../config.json')['test'];

describe('isValid Test', () => {
  it('Should redirects an error when the url is not valid', async () => {
    stub.withArgs(url).rejects('Not Valid');

    const { status } = await request(server).get('/');

    expect(status).to.equal(400);
  });
});

Кроме того, чтобы перестать видеть отклонение необработанного обещания при выполнении тестов, вы можете использовать .rejects() функция вместо создания собственного отклоненного обещания.

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