web-dev-qa-db-fra.com

Quel est le meilleur moyen d'écrire les spécifications pour le code qui dépend de variables d'environnement?

Je teste un code qui tire sa configuration de variables d’environnement (définies par les configurations de configuration Heroku en production, pour le développement local, j’utilise contremaître).

Quel est le meilleur moyen de tester ce type de code avec RSpec?

Je suis venu avec ceci:

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

Si vous n'avez pas besoin de tester différentes valeurs des variables d'environnement, vous pouvez les définir dans spec_helper.

46
Luke Francl

Ça marcherait.

Vous pouvez également mettre une couche d'indirection entre votre code et les variables d'environnement, comme un objet de configuration facile à simuler.

22
nicholaides

Vous pouvez également stub la constante:

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

Ou, si vous voulez toujours le reste de l’ENV:

stub_const('ENV', ENV.to_hash.merge('AWS_ACCESS_KEY_ID' => 'asdf'))
51
iGEL

Comme le suggère Heroku suggère , vous pouvez utiliser le fichier .env de Foreman pour stocker les variables d'environnement pour le développement.

Si vous faites cela, vous pouvez utiliser foreman run pour exécuter vos spécifications:

foreman run bundle exec rspec spec
6
ciastek

J'éviterais ENV.stub (: []). Cela ne fonctionnera pas si d'autres éléments utilisent ENV, tels que le levier (vous obtiendrez une erreur indiquant que vous devez remplacer DISUBBACK_PRY). 

stub_const fonctionne bien comme déjà indiqué.

2
Calvin

Vous pouvez utiliser https://github.com/littleowllabs/stub_env pour y parvenir. Il vous permet de remplacer des variables d’environnement individuelles sans toutes les remplacer, comme le suggère votre solution.

Installez la gem puis écrivez 

before :each do
  stub_env('AWS_ACCESS_KEY_ID', 'asdf')
  stub_env('AWS_SECRET_ACCESS_KEY','secret')
end
2
Liam Bennett

Si vous utilisez dotenv pour configurer votre environnement pendant les tests mais que vous devez modifier une variable env pour un test spécifique, l'approche suivante peut être utile. 

Une méthode plus simple que le stubbing ENV consiste à remplacer l'environnement pour la durée du test, puis à le restaurer ultérieurement, comme suit:

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

En utilisant un assistant comme celui-ci (de source Homebrew ):

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

En utilisant ensure, l'environnement d'origine est restauré même si le test échoue.

Il existe une comparaison pratique des méthodes pour définir et modifier les variables d'environnement pendant les tests y compris le remplacement de la ENV, le remplacement des valeurs avant/après le test et des gemmes comme ClimateControl.

1
odlp

Ce que vous voulez, c'est le gem dotenv .

Comme @ciastek le suggère, l'exécution de tests sous Foreman fonctionne très bien lors de l'exécution de spécifications à partir de la CLI. Mais cela ne m'aide pas à exécuter les spécifications avec Ruby Test dans Sublime Text 2. Dotenv fait exactement ce que vous voulez, de manière transparente.

1
Tim Scott

Cette syntaxe fonctionne pour moi:

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
0
aldrien.h