如何将外部对象传递给rspec测试?

时间:2014-05-14 14:17:10

标签: ruby rspec

我有一系列RSpec测试 - 每个测试都存在于自己的文件中 - 所有这些测试都需要运行一个特定的对象(shop)。

由于设置shop对象很复杂,我希望有一个构建shop对象的主文件,然后依次将它传递给所有RSpec测试文件。我们的想法是,编写测试脚本的人不需要了解设置步骤。

我无法弄清楚如何将来自外部世界的东西带入rspec测试案例。我试过各种各样的变化:

file master.rb:

describe "Testing tests/some_test.rb" do
  before :all do
    @shop = some_complex_operations
  end
  load 'tests/some_test.rb'
end

file tests / some_test.rb:

describe 'Some feature' do
  it 'should know about @shop'
    expect(@shop).not_to be nil
  end
end

当我运行rspec master.rb时,some_test.rb会失败。

我知道我概述的内容可能是一种非常错误的方法,但我希望至少你明白这一点。

我怎样才能干净利落地完成这件事?

2 个答案:

答案 0 :(得分:1)

您需要的是global hook

您可以创建spec_helper并在所有全局挂钩之前添加一个。例如:

RSpec.configure do |config|
  config.before(:each) do
    @shop = "in case you need a fresh instance of shop each time"
  end
  config.before(:all) do
    @shop = "in case you need a single instance (i.e. you don't modify it)"
  end
end

然后你应该从你的每个规范中要求这个助手。 spec_helper可以存储任何全局挂钩以及帮助程序或其他依赖项。

答案 1 :(得分:0)

在编写测试时,应测试一个事物。 shop可能是一个非常复杂的对象,许多对象和方法都与之交互,但我猜他们 none 都知道shop的复杂性 - 每种方法都有兴趣在shop方面中。

因此,我建议不要为每个测试构建一个复杂的对象,而是创建一个double,使其期望相关的内容,然后只需存根其余的:

describe 'Some feature' do
  let(:shop) { double('shop').as_nil_object }
  let(:my_object) { MyClass.new(shop: shop) }


  it 'should do something awesome with shop' do
    expect(shop).to receive(:awesome_data).and_return(my_data: 'is_this')

    expect(my_object.do_something_awesome).to eq 'how awesome is_this?'
  end
end