Ruby中的存根文件

时间:2018-09-19 11:18:20

标签: ruby rspec

我有一个想在rspec文件中存根的ruby方法:

  def load_environment_config(gateway, trx_type)
    @config = YAML.load_file("config/#{env}.yml")["#{env.upcase}"]
    raise "\n\nMissing gateway configuration for #{gateway} in file config/#{env}.yml!\n" unless @config[gateway]
    @terminal = terminal_for(@config, gateway, trx_type)
    @url = URI.parse("#{@config['processing_url']}#{@terminal['token']}")
  end

我尝试过:

let(:request_builder) { described_class.new(env: nil) } 
  let(:trx_types)       { ['davivienda'] }
  let(:trx_type)        { 'davivienda' }
  let(:gateway)         { 'girogate' }
  let(:currency)        { 'USD' }
  let(:base_params)     { request_builder.send(:base_params) }

  before(:each) { allow(request_builder).to receive(:currency).and_return(currency) }

  let(:yaml_file) { YAML::load(File.read(File.join('spec', 'fixtures', 'yaml', 'test_env.yml'))) }
  let(:config)    { yaml_file['TEST_ENV'] }
  let(:successful_response_file) { File.read(File.join('spec', 'fixtures', 'xml', 'successful_response.xml')) }

  allow(request_builder).to receive(:currency).and_return('EUR') 
  allow(request_builder).to receive(:env).and_return('TEST_ENV') 
  allow(request_builder).to receive(:config).and_return(config) 
  allow(request_builder).to receive(:base_params).and_return(base_params)
  allow(request_builder).to receive(:gateway).and_return(gateway)  
  allow(request_builder).to receive(:request_builder)

但是当我运行rspec代码时,我得到了:

Errno::ENOENT:
       No such file or directory @ rb_sysopen - config/TEST_ENV.yml
     # ./models/request_builder.rb:50:in `load_environment_config'
     # ./models/request_builder.rb:45:in `filter_trx_types_list_for'
     # ./models/request_performer.rb:8:in `process_trx'
     # ./models/request_builders/girogate_request_builder.rb:81:in `block in submit!'
     # ./models/request_builders/girogate_request_builder.rb:80:in `each'
     # ./models/request_builders/girogate_request_builder.rb:80:in `submit!'
     # ./spec/models/request_builders/girogate_request_builder_spec.rb:42:in `block (3 levels) in <top (required)>'

我的想法是对变量config存根,并使用位于spec目录中的yaml文件。覆盖@config的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我将进行更改,以便根据该函数调用的结果设置实例变量,并从该函数中删除所有instance_variables。

  def load_environment_config(gateway, trx_type)
    config = YAML.load_file("config/#{env}.yml")["#{env.upcase}"]
    raise "\n\nMissing gateway configuration for #{gateway} in file config/#{env}.yml!\n" unless config[gateway]
    terminal = terminal_for(config, gateway, trx_type)
    url = URI.parse("#{config['processing_url']}#{terminal['token']}")
    [ url, terminal,  config]
  end

  # Then whereever you call the loader becomes
  @url, @terminal, @config = load_environment_config(some_gateway, some_trx)

进行此更改后,就可以对stub_environment_config的所有详细信息进行模拟或显示

  expect(:your_instance).to_receive(:load_environment_config) { [url, terminal, config] }

如果您认为这对规范很重要,则可能要走得更远些,并接受with_arguments


不改变load_environment_config功能的解决方案

your_instance.stub(:load_environment_config)
your_instance.instance_variable_set(:@config, some_value)
your_instance.instance_variable_set(:@terminal, some_value)
your_instance.instance_variable_set(:@url, some_value)

答案 1 :(得分:0)

也许您可以使用rails方法来获取正确的env,例如:

file_path = File.join(Rails.root, 'config', "#{Rails.env}.yml"
@config = YAML.load_file(filepath)["#{Rails.env.upcase}"]

因此,您至少需要三个新文件:

{root}/config/test.yml
{root}/config/development.yml
{root}/config/production.yml

有了这个,您不需要存根文件加载过程