问题
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