node.js에서 process.env를 스텁하는 방법은 무엇입니까?


81

나는 스텁 할 process.env.FOO함께 bar.

var sinon = require('sinon');
var stub = sinon.stub(process.env, 'FOO', 'bar');

혼란 스럽습니다. 문서를 읽었지만 아직 이해가되지 않습니다. sinonjs 문서

sinonjs는 하나의 예이며 sinonjs는 괜찮습니다.


환경 변수를 스텁하려는 이유를 설명 할 수 있습니까? 유닉스 계열 OS 또는 Windows에서이 작업을 수행하고 있습니까?
slebetman

1
@slebetman 사용자가 의존하는 서비스의 API 키와 같이 구성을 위해 환경 변수에 의존하는 것이 일반적입니다. 12factor.net을 참조하십시오 .
Andrew Homeyer 2015-07-30

1
@AndrewHomeyer : 네,하지만 당신은하지 않는 스텁 을 - 검사에 올바르게 설정
slebetman

답변:


74

에 대한 내 이해에서 process.env속성을 설정할 때 다른 변수처럼 간단히 처리 할 수 ​​있습니다. 하지만의 모든 값 process.env은 문자열이어야합니다. 따라서 테스트에서 특정 값이 필요한 경우 :

   it('does something interesting', () => {
      process.env.NODE_ENV = 'test';
      // ...
   });

상태가 다른 테스트로 누출되지 않도록하려면 변수를 원래 값으로 재설정하거나 모두 삭제해야합니다.

   afterEach(() => {
       delete process.env.NODE_ENV;
   });

8
그것은 나를 위해 작동합니다. 한 가지 명심해야 할 점은 모듈이 처음로드 될 때 NODE_ENV를 읽는 모듈을 테스트하는 경우 모듈을로드 하기 전에 NODE_ENV를 설정해야한다는 것입니다 (즉, NODE_ENV는 beforeEach 블록에서 설정할 수 있음). , 그러나 그것은 전에 나를 걸려 넘어졌습니다.
Terrence

문제가있는 경우 다른 사람이 볼 수 있도록 코드 스 니펫을 게시 할 수 있습니까? Mocha 테스트 실행기의 구문을 염두에두고 답을 작성했지만 다른 실행기에서도 작동합니다 (예 : 실험실).
Joshua Dutton

2
이것은 작동하지만 jest. 내 프로덕션 코드에서 env에서 const (예 :)로 할당했습니다 const X = process.env.X. const는 함수 범위가 아닌 (ES) 모듈 범위에서 선언되었습니다. 내 테스트는 항상 jest --watch재 시도 된 테스트 실행에서 통과 했지만 항상 첫 번째 실행에서는 실패했습니다. 여기서 완전히 이해하지 못하는 주문 문제가 있습니다. 항상 process.env프로덕션 코드 (즉, 함수)에서 직접 읽고 있고 모듈 수준에서 캐싱하지 않는지 확인하십시오.
Jesse Buchanan

1
이것은 함수에서 process.env를 평가하는 경우 잘 작동하지만 상수 인 경우에는 작동하지 않습니다. 예를 들어 const myValue = process.env.value ? process.env.value : 'default'테스트 내에서 process.env.value를 설정하면 작동하지 않았습니다. 그러나 const myValue = () => (process.env.value ? process.env.value : 'default')는 예상대로 작동합니다!
Rafael Marques

이 같은 맥락에서 저는 다음과 같이했습니다. const SWITCH_ON = (process.env.SWITCH_ON.toLowerCase() === 'true');작동하지 않아서 두 줄로 변경했습니다 var switchOn = process.env.SWITCH_ON; const SWITCH_ON = (switchOn === undefined ? false : switchOn.toLowerCase() === 'true');. 이니셜은 undefined제가하고 있던 곳에서 계속 오류를 발생 시켰 습니다.toLowerCase()
Scala Enthusiast

25

나는 process.env그것을 복제하고 그것을 복원하는 분해 방법으로 내 단위 테스트에서 적절하게 stubed 될 수있었습니다 .

Mocha를 사용한 예

const env = Object.assign({}, process.env);

after(() => {
    process.env = env;
});

...

it('my test', ()=> {
    process.env.NODE_ENV = 'blah'
})

이것은 process.env가 테스트중인 함수에서만 읽는 경우에만 작동합니다. 예를 들어 테스트중인 코드가 변수를 읽고 클로저에서 사용하면 작동하지 않습니다. 제대로 테스트하기 위해 캐시 된 요구 사항을 무효화 할 수 있습니다.

예를 들어 다음은 env가 스텁되지 않습니다.

const nodeEnv = process.env.NODE_ENV;

const fnToTest = () => {
   nodeEnv ...
}

3
이 과정은 대부분 효과가있었습니다. "이후"방법을 조정해야했습니다. after(() => { process.env = Object.assign({}, env); }); 그렇지 않으면 테스트가 공유 사본을 조작합니다. 각 테스트 후 새로운 버전을 설정해야합니다.
Kyle

1
@Kyle .. 아니 그럴까요? 파일의 상단에, 그것은 당신의 테스트 스위트의 시작 부분에 무엇으로 복원됩니다 일단 .. 당신에게 설정 ENV 가정
죄수

4

A의 spec-helper.coffee당신이 당신의 sinon 샌드 박스를 설정하는 곳이나 뭐 비슷한, 원래의 추적 process.env당신이 검사 사이에 누설하지 않는 모든 시간을 다시 기억하지 않아도, 각 시험 후 복원합니다.

_ = require 'lodash'
sinon = require 'sinon'

beforeEach ->
    @originalProcessEnv = _.cloneDeep process.env

afterEach ->
    process.env = _.cloneDeep @originalProcessEnv

테스트에서 process.env정상적으로 사용하십시오 .

it 'does something based on an env var', ->
    process.env.FOO = 'bar'

underscoreclone기능을 대신 작동 cloneDeep이미 사용하는 경우 유용합니다 - underscore보다는 lodash.
Rob

4

sinon을 사용하면 이와 같은 변수를 스텁 할 수 있습니다.

 const myObj = {
    example: 'oldValue', 
 };

 sinon.stub(myObj, 'example').value('newValue');

 myObj.example; // 'newValue'

이 예제는 sinon 문서 양식입니다. https://sinonjs.org/releases/v6.1.5/stubs/


이러한 지식으로 모든 환경 변수를 스텁 할 수 있습니다. 귀하의 경우에는 다음과 같이 보일 것입니다.

 let stub = sinon.stub(process.env, 'FOO').value('bar');

5
'존재하지 않는 소유 속성 FOO를 스텁 할 수 없습니다'라는 오류 메시지가 표시됩니다. 내 테스트를 실행하기 위해 wallaby.js도 사용합니다.
Will Lovett

1
"환경 변수 스터 빙은 어떻게 생겼습니까?"라는 질문에 대한 답변을 게시 해 주셔서 감사합니다. 수동으로 조작 할 수 있기 때문에 필요하지 않다고 말하는 대신 :)
Will

@WillLovett와 동일한 오류가 발생하여 단위 테스트 스크립트 상단 근처에 require 호출을 추가하여 해결했습니다. require('dotenv').config();애플리케이션이 실행될 때 일반적으로 호출된다는 것을 깨달았지만 단위 테스트를 직접 실행하는 경우 require 문이 누락되었습니다.
Von Pittman

4

단위 테스트 중에 process.env를 빠르게 모의하는 방법.

https://glebbahmutov.com/blog/mocking-process-env/

const sinon = require('sinon')
let sandbox = sinon.createSandbox()

beforeEach(() => {
  sandbox.stub(process.env, 'USER').value('test-user')
})

it('has expected user', () => {
  assert(process.env.USER === 'test-user', 'wrong user')
})

afterEach(() => {
  sandbox.restore()
})

그러나 테스트 전에 process.env에 존재하지 않을 수있는 속성은 어떻습니까? 다음 패키지를 사용하면 존재하지 않는 환경 변수를 테스트 할 수 있습니다.

https://github.com/bahmutov/mocked-env


process.env.USER아직 값 이 없으면 작동 하지 않습니다.
Sohail Si

0

process.env에없는 키를 스텁하려면 이것을 사용할 수 있습니다.

const sinon = require('sinon')
let sandbox = sinon.createSandbox();
sandbox.stub(process, 'env').value({ 'SOME_KEY': 'SOME_VALUE' });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.