使用rspec对Rails.env.development进行模拟测试

38

我正在使用rspec编写单元测试。

我想要模拟Rails.env.development?返回true。我该如何实现?

我尝试过这样做:

Rails.env.stub(:development?, nil).and_return(true)

它抛出了这个错误

activesupport-4.0.0/lib/active_support/string_inquirer.rb:22:in `method_missing': undefined method `any_instance' for "test":ActiveSupport::StringInquirer (NoMethodError)

更新 Ruby 版本为 ruby-2.0.0-p353,Rails 版本为 4.0.0,Rspec 版本为 2.11。

describe "welcome_signup" do
    let(:mail) { Notifier.welcome_signup user }

    describe "in dev mode" do
      Rails.env.stub(:development?, nil).and_return(true)
      let(:mail) { Notifier.welcome_signup user }
      it "send an email to" do
        expect(mail.to).to eq([GlobalConstants::DEV_EMAIL_ADDRESS])
      end
    end
  end
3个回答

81

这里描述了一种更好的方法:https://dev59.com/Dm855IYBdhLWcg3wj1QS#24052647

it "should do something specific for production" do 
  allow(Rails).to receive(:env) { "production".inquiry }
  #other assertions
end

这将提供所有功能,例如Rails.env.test?,并且也适用于仅比较字符串的情况,如Rails.env == 'production'


3
这是使用 RSpec 3 的方法。 - d_rail
16
获取一个询问对象的更简洁的方法是执行 "production".inquiry - David Backeus
@DavidBackeus:我不同意,我认为Rails将对象与无关行为混合在一起的方式并不干净,但它确实很方便。谢谢 - iGEL

22

你应该在itletbefore块中进行存根。将你的代码移动到那里,它就会工作。

这段代码在我的测试中有效(也许你的变体也可以工作)。

Rails.env.stub(:development? => true)

例如

describe "in dev mode" do
  let(:mail) { Notifier.welcome_signup user }

  before { Rails.env.stub(:development? => true) }

  it "send an email to" do
    expect(mail.to).to eq([GlobalConstants::DEV_EMAIL_ADDRESS])
  end
end

2
没有真正帮助到你。出现 method_missing': undefined method stub' for "test":ActiveSupport::StringInquirer (NoMethodError) 错误。 - ssinganamalla
奇怪 - 在发布代码之前,我检查了我的测试。请提供您的代码和宝石版本(rails,rspec)。 - gotva
谢谢,它起作用了。那么将其放置在 it、let 或 before 块中的原因是什么?我认为“发送电子邮件至”块应该可以访问外部 describe 块中的任何内容。 - ssinganamalla
找到了。http://stackoverflow.com/questions/11955733/stub-for-class-in-rspec2/11955986#11955986 - ssinganamalla
并不是那么简单。这是一个相当复杂的问题。如果用两个词来说:stubRspec 的一个方法,而 Rspec 只在所提到的代码块内工作。另一个原因是你应该在调用方法之前存根它,但当你启动测试时 - Rspec 只读取需要的行:before allbefore eachit 代码块(let 代码块是惰性加载)。 - gotva

2

使用 RSpec 3:

allow(Rails).to receive(:env).and_return(OpenStruct.new(staging?: true))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接