Каков наилучший способ написать спецификации для кода, который зависит от переменных среды? - PullRequest
51 голосов
/ 08 марта 2012

Я тестирую некоторый код, который извлекает свою конфигурацию из переменных среды (устанавливается в конфигурации с помощью Heroku vars, для локальной разработки я использую мастер).

Как лучше всего протестировать этот вид кода с помощью RSpec?

Я придумал это:

before :each do
    ENV.stub(:[]).with("AWS_ACCESS_KEY_ID").and_return("asdf")
    ENV.stub(:[]).with("AWS_SECRET_ACCESS_KEY").and_return("secret")
end

Если вам не нужно тестировать различные значения переменных среды, я думаю, вы могли бы установить их в spec_helper.

Ответы [ 8 ]

55 голосов
/ 13 ноября 2013

Вы также можете заглушить константу:

stub_const('ENV', {'AWS_ACCESS_KEY_ID' => 'asdf'})

Или, если вы все еще хотите остаток ENV:

stub_const('ENV', ENV.to_hash.merge('AWS_ACCESS_KEY_ID' => 'asdf'))
22 голосов
/ 08 марта 2012

Это будет работать.

Другим способом было бы поместить слой косвенности между вашим кодом и переменными окружения, как какой-то объект конфигурации, который легко смоделировать.

7 голосов
/ 12 июня 2012

Поскольку Heroku предлагает , вы можете использовать файл Foreman .env для хранения переменных среды для разработки.

Если вы сделаете это, вы можете использовать foreman run для запуска своих спецификаций:

foreman run bundle exec rspec spec
3 голосов
/ 04 января 2017

Если вы используете dotenv для настройки вашей среды во время тестов, но вам нужно изменить переменную env для конкретного теста , тогда может пригодиться следующий подход.

Более простой метод, чем заглушка ENV, состоит в том, чтобы заменить среду на время теста, а затем восстановить ее следующим образом:

with_environment("FOO" => "baz") do
  puts ENV.fetch("FOO")
end

Используя такой помощник (из Доморощенный источник ):

module Test
  module Helper
    module Env
      def with_environment(partial_env)
        old = ENV.to_hash
        ENV.update partial_env
        begin
          yield
        ensure
          ENV.replace old
        end
      end
    end
  end
end

При использовании ensure исходная среда восстанавливается, даже если тест не пройден.

Существует удобное сравнение методов для установка и изменение переменных среды во время тестов , включая заглушку ENV, замену значений до / после теста и драгоценных камней, таких как ClimateControl.

2 голосов
/ 06 ноября 2014

Вы можете использовать https://github.com/littleowllabs/stub_env для достижения этой цели. Это позволяет вам заглушить отдельные переменные среды, не заглушая их все, как предложено вашим решением.

Установите гем, затем напишите

before :each do
  stub_env('AWS_ACCESS_KEY_ID', 'asdf')
  stub_env('AWS_SECRET_ACCESS_KEY','secret')
end
2 голосов
/ 27 февраля 2014

Я бы избегал ENV.stub (: []) - он не работает, если другие вещи используют ENV, такие как pry (вы получите ошибку о необходимости заглушить DISABLE_PRY).

stub_const работает хорошо, как уже отмечалось.

1 голос
/ 06 сентября 2018

Этот синтаксис работает для меня:

module SetEnvVariable

  def set_env_var(name, value)
   # Old Syntax
   # ENV.stub(:[])
   # ENV.stub(:[]).with(name).and_return(value)

   allow(ENV).to receive(:[]) # stub a default value first if message might be received with other args as well.
   allow(ENV).to receive(:[]).with(name).and_return(value)
  end

end
1 голос
/ 05 июня 2013

Что вам нужно, так это dotenv gem .

Запуск тестов под мастером, как подсказывает @ciastek, прекрасно работает при запуске спецификаций из CLI.Но это не помогает мне запускать спецификации с помощью Ruby Test в Sublime Text 2. Dotenv делает именно то, что вы, прозрачно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...