Mam aplikację, która zależy od zmiennych środowiskowych, takich jak:
const APP_PORT = process.env.APP_PORT || 8080;
i chciałbym to przetestować np .:
- APP_PORT można ustawić za pomocą zmiennej env węzła.
- lub że
express
aplikacja działa na porcie ustawionym zprocess.env.APP_PORT
Jak mogę to osiągnąć dzięki Jest? Czy mogę ustawić te process.env
zmienne przed każdym testem, czy może powinienem jakoś z tego kpić?
node.js
testing
environment-variables
jestjs
Tomasz Mularczyk
źródło
źródło
Odpowiedzi:
Sposób, w jaki to zrobiłem, można znaleźć w tym pytaniu SO .
Ważne jest, aby zresetować moduły przed każdym testem, a następnie dynamicznie zaimportować moduł wewnątrz testu:
describe('environmental variables', () => { const OLD_ENV = process.env; beforeEach(() => { jest.resetModules() // most important - it clears the cache process.env = { ...OLD_ENV }; // make a copy }); afterAll(() => { process.env = OLD_ENV; // restore old env }); test('will receive process.env variables', () => { // set the variables process.env.NODE_ENV = 'dev'; process.env.PROXY_PREFIX = '/new-prefix/'; process.env.API_URL = 'https://new-api.com/'; process.env.APP_PORT = '7080'; process.env.USE_PROXY = 'false'; const testedModule = require('../../config/env').default // ... actual testing }); });
Jeśli szukasz sposobu na załadowanie wartości env przed uruchomieniem Jest, poszukaj odpowiedzi poniżej . Powinieneś do tego użyć setupFiles .
źródło
delete process.env.NODE_ENV;
jest tylko pozostałością z mojego kodu i nie powinno mieć znaczenia w Twoim przypadku. Liczy się to, że dzwoniszjest.resetModules()
przed testem, a po nim przywracasz początkowy obiekt process.env (OLD_ENV)Jest
setupFiles
to właściwy sposób radzenia sobie z tym problemem i nie musisz instalowaćdotenv
ani.env
w ogóle używać pliku, aby działał.jest.config.js
:module.exports = { setupFiles: ["<rootDir>/.jest/setEnvVars.js"] };
.jest/setEnvVars.js
:process.env.MY_CUSTOM_TEST_ENV_VAR = 'foo'
Otóż to.
źródło
W
./package.json
:"jest": { "setupFiles": [ "<rootDir>/jest/setEnvVars.js" ] }
W
./jest/setEnvVars.js
:process.env.SOME_VAR = 'value';
źródło
Możesz skorzystać z
setupFiles
funkcji jest config. Jako dokumentacja mówi , żenpm install dotenv
dotenv, który używa do uzyskania dostępu do zmiennej env..env
plik w katalogu głównym aplikacji i dodaj do niego ten wiersz.#.env APP_PORT=8080
//someModuleForTest.js require("dotenv").config()
jest.config.js
plik w ten sposóbmodule.exports = { setupFiles: ["./someModuleForTest"] }
test("Some test name", () => { expect(process.env.APP_PORT).toBe("8080") })
źródło
Inną opcją jest dodanie go do
jest.config.js
pliku pomodule.exports
definicji:process.env = Object.assign(process.env, { VAR_NAME: 'varValue', VAR_NAME_2: 'varValue2' });
Dzięki temu nie ma potrzeby definiowania
ENV
zmiennych w każdym.spec
pliku i można je dostosowywać globalnie.źródło
W zależności od tego, jak możesz zorganizować swój kod, inną opcją może być umieszczenie zmiennej env w funkcji wykonywanej w czasie wykonywania.
W tym pliku zmienna env jest ustawiana w czasie importu i wymaga dynamicznych wartości
require
w celu przetestowania różnych zmiennych środowiska (zgodnie z opisem w tej odpowiedzi ):const env = process.env.MY_ENV_VAR; const envMessage = () => `MY_ENV_VAR is set to ${env}!`; export default myModule;
W tym pliku zmienna env jest ustawiana w
envMessage
czasie wykonywania i powinieneś być w stanie zmutować process.env bezpośrednio w swoich testach:const envMessage = () => { const env = process.env.MY_VAR; return `MY_ENV_VAR is set to ${env}!`; } export default myModule;
Test jest:
const vals = [ 'ONE', 'TWO', 'THREE', ]; vals.forEach((val) => { it(`Returns the correct string for each ${val} value`, () => { process.env.MY_VAR = val; expect(envMessage()).toEqual(...
źródło
Rozwijam nieco odpowiedź Serhana C. ( https://stackoverflow.com/a/57944454/2708174 ) ...
zgodnie z tym blogiem https://tekloon.dev/using-dotenv-with-jest możesz dołączyć
"dotenv/config"
bezpośredniosetupFiles
, bez konieczności tworzenia i odwoływania się do zewnętrznego skryptu, który wywołujerequire("dotenv").config()
.czyli po prostu zrób
module.exports = { setupFiles: ["dotenv/config"] }
źródło
Myślę, że ty też możesz spróbować:
const currentEnv = process.env; process.env = { ENV_NODE: 'whatever' }; // test code... process.env = currentEnv;
To działa dla mnie i nie potrzebujesz rzeczy modułowych
źródło
Moim zdaniem jest znacznie czystszy i łatwiejszy do zrozumienia, jeśli wyodrębnisz pobieranie zmiennych środowiskowych do narzędzia (prawdopodobnie chcesz dołączyć sprawdzenie, czy szybko się nie powiedzie, jeśli zmienna środowiskowa i tak nie jest ustawiona), wtedy możesz po prostu mockować narzędzie .
// util.js exports.getEnv = (key) => { const value = process.env[key]; if (value === undefined) { throw new Error(`Missing required environment variable ${key}`); } return value; }; // app.test.js const util = require('./util'); jest.mock('./util'); util.getEnv.mockImplementation(key => `fake-${key}`); test('test', () => {...});
źródło