2012-02-04 37 views
11

如何将模块混合到rspec上下文中(又名describe),使模块的常量可用于规范?如何将模块混合到rspec上下文中

module Foo 
    FOO = 1 
end 

describe 'constants in rspec' do 

    include Foo 

    p const_get(:FOO) # => 1 
    p FOO    # uninitialized constant FOO (NameError) 

end 

const_get可以检索不变时,常量的名称不能是有趣的。什么导致rspec的好奇行为?

我正在使用MRI 1.9.1和rspec 2.8.0。症状与MRI 1.8.7相同。

+0

您正在使用哪个Ruby版本? – 2012-02-04 14:16:58

+0

@John,MRI 1.9.1 – 2012-02-04 14:31:30

回答

10

可以使用的RSpec的shared_context

shared_context 'constants' do 
    FOO = 1 
end 

describe Model do 
    include_context 'constants' 

    p FOO # => 1 
end 
+0

自从我学习了一个关于rspec的新酷东西已经有一段时间了。非常好。 – steve 2013-01-03 22:40:38

11

你想extend,不include。这适用于红宝石1.9.3,例如:

module Foo 
    X = 123 
end 

describe "specs with modules extended" do 
    extend Foo 
    p X # => 123 
end 

另外,如果你想重用在不同的测试一个RSpec情况下,使用shared_context

shared_context "with an apple" do 
    let(:apple) { Apple.new } 
end 

describe FruitBasket do 
    include_context "with an apple" 

    it "should be able to hold apples" do 
    expect { subject.add apple }.to change(subject, :size).by(1) 
    end 
end 

如果你想重用在不同的规格上下文,使用shared_examplesit_behaves_like

shared_examples "a collection" do 
    let(:collection) { described_class.new([7, 2, 4]) } 

    context "initialized with 3 items" do 
    it "says it has three items" do 
     collection.size.should eq(3) 
    end 
    end 
end 

describe Array do 
    it_behaves_like "a collection" 
end 

describe Set do 
    it_behaves_like "a collection" 
end 
+0

我也尝试过'extend',但是我仍然有'NameError'。甚至更奇怪的是,当我尝试了'include Foo'和'p(constants - Object.constants)'时,常量'X'显然在列表中,但我不能直接引用它 - 只能通过const_get来引用它。这是Ruby 1.8.7。 – Brandan 2012-02-04 14:29:14

+0

@Brandan,'extend'在这里也不起作用。 – 2012-02-04 14:37:11

+0

在1.8.7中,'extend'在RSpec上下文中稍有不同。我在1.9.3上。 – 2012-02-04 14:41:09