Как издеваться над константой, которая является зависимостью тестируемой службы?

Я тестирую файл с именем connect-key.js. У него есть зависимость под названием keyvault-emulator.

Файл №1:

// connect-key.js file
const { save, retrieve, init  } = require('./keyvault-emulator')
....
....
....
// SOME TESTS

Файл №2:

// The keyvault-emulator.js file
const { storageConnectionString } = require('../config')

Теперь, как я могу смоделировать значение storageConnectionString из моего тестового файла connect-key.spec.js?

Я представляю что-то вроде этого:

// The connect-key.spec.js file
const keyvault_emulator = require('../keyvault-emulator');
const spy = jest.spyOn(keyvault_emulator, 'storageConnectionString');
spy.mockReturnValue('');

А это файл конфигурации:

// config.js file
module.exports = {
  storageConnectionString: process.env.STORAGE_CONNECTION_STRING || process.env.Storage,
  keyVaultName: process.env.KEY_VAULT
}

Это правильный способ сделать это? Каков наилучший способ добиться этого?

Поведение ключевого слова "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) для оценки ваших знаний,...
0
0
109
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Насмешка над внутренней зависимостью

Прежде чем издеваться над внутренней зависимостью, вопрос должен прояснить, в чем ее смысл; потому что насмешливые способности Джеста несколько ограничены. Поскольку это не было упомянуто в вопросе, я лично выбрал несколько наилучших возможных случаев с примерами.

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

1. только для конкретной функции в области тестирования, ничего больше.

// key.spec.js
const keyvault_emulator = require('../keyvault-emulator');
js.mock('../keyvault-emulator', () => ({
  // everything is original, except testFunction
  ...jest.requireActual('../keyvault-emulator'),
  // this supposed to return () => storageConnectionString but it's mocked here.
  testFunction: jest.fn(() => 'mocked')
})

// ✅ it works
expect(keyvault_emulator.testFunction()).toEqual('mocked')
// ❌ this fails!
expect(keyvault_emulator.otherFunctionUsingStorageConnectionString())
  .toEqual('mocked')

2. для всего внутри модуля

Jest может заменить только функцию или модуль. Он не может переоценивать коды. В этом случае зависимость config.js и keyvault-emulator.js должна быть отделена от источника, чтобы упростить процесс тестирования.

2-1. жесткая отвязка от самого источника.

// keyvault-emulator.js
// KeyValue emulator has to be restructured to have constructor, or init function
class KeyValueEmulator {
  constructor(config) {
    this.config = config;
  }
  testFunction() {
    // do something with this.config
    return this.config;
  }
}

// key.spec.js
const mockedConfig = { storageConnectionConfig: 'mocked' }
const keyValueEmulator = new KeyValueEmulator(mockedConfig);
// ✅ it works
expect(keyValueEmulator.testFunction()).toEqual('mocked')

2-2. мягкая развязка с издевательством над внутренним модулем шутки.

рабочие коды на Github

// key.spec.js
import config from "./config";
jest.mock("./config", () => ({ default: { storageConnectionString: "mocked" } }));
import { storageConnectionString, testFunction } from "./index";

describe("config mocking", () => {
  it("value is mocked", () => {
    // ✅ it works
    expect(config.storageConnectionString).toEqual("mocked");
    expect(testFunction()).toEqual("mocked");
  });
});

3. издевательство над одной переменной

Как уже объяснялось в случае 2, это невозможный случай. Jest просто не может издеваться над одной переменной; он, вероятно, наиболее близок к коду, упомянутому в вопросе, и поэтому необходимо уточнение.

// same as code in the question. the test code should be fixed to work,
// but let's say it's working as you've intended.
// key.spec.js
const keyvault_emulator = require('../keyvault-emulator');
const spy = jest.spyOn(keyvault_emulator, 'storageConnectionString');
spy.mockReturnValue('mocked');
// ✅ it may work...but
expect(keyvault_emulator.storageConnectionString).toEqual('mocked')
// ❌ this fails!
expect(keyvault_emulator.testFunction()).toEqual('mocked')

Итак, как лучше всего?

Это правильный способ сделать это? Каков наилучший способ добиться этого?

Как и во многих случаях в мире разработчиков, это зависит от случая. Лично я бы выбрал метод жесткой развязки, упомянутый в 2-1, для общего использования, но во многих случаях он не подходит идеально. Выберите тот, который лучше всего подходит для вашего случая.

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