How to stub i18n_scope for mocking ActiveRecord::RecordInvalid on Rails 4 rspec 3.3.0?

拜拜、爱过 提交于 2019-12-10 20:59:35

问题


I have tried this code but it raises the error: NameError: uninitialized constant RSpec::Mocks::Mock

RSpec::Mocks::Mock.stub(:i18n_scope).and_return(:activerecord)
model = double(:model, errors: double(:errors, full_messages: []))
ActiveRecord::RecordInvalid.new(model)

How can I stub i18n_scope?


回答1:


To answer your question, you have to stub RSpec::Mocks::Double because that's the class of the instance you're actually passing to ActiveRecord::RecordInvalid. However, that won't work because RSpec::Mocks::Double doesn't implement .i18n_scope. So, what I did (and I hate it) was monkey-patch the RSpec::Mocks::Double class with a dummy method.

  it "does something cool" do
    foo = MyClass.new
    class RSpec::Mocks::Double
      def self.i18n_scope
        :activerecord
      end
    end
    error_double = double(:model, errors: double(:errors,full_messages: ["blah"]))
    expect(foo).to receive(:bar).and_raise(ActiveRecord::RecordInvalid, error_double)
    ...
  end

But there's a better way of doing this by taking advantage of a block argument:

  it "does something cool" do
    foo = MyClass.new
    expect(foo).to receive(:bar) do |instance|
      instance.errors.add(:base, "invalid error")
      raise(ActiveRecord::RecordInvalid, instance)
    end
    ...
  end

This way, you're testing much closer to your application data / logic vs. hacking RSpec.

This worked perfectly for a controller test where I was rescuing from a specific error that was thrown from an #update! method in certain situations.



来源:https://stackoverflow.com/questions/33037136/how-to-stub-i18n-scope-for-mocking-activerecordrecordinvalid-on-rails-4-rspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!