How to use rspec-mocks
Bài đăng này đã không được cập nhật trong 8 năm
I. Introduction
- What is rspec-mocks? It's a framework for rspec with helps to control the context in a code example by letting you set known return values, fake implementations of methods, and even set expectations that specific messages are received by an object.
II. Installation
- Rspec-mocks is also integrate in rspec gem that be installed by this command:
gem install rspec
- It can be installed separately by this command:
gem install rspec-mocks
III. Simple example
In this example, we need to write rspec for this method:
class UpdateUserAndSubject
class << self
dev perform user, subject
ActiveRecord::Base.transaction do
user.update_attributes! params[:user]
subject.update_attributes! params[:subject]
end
rescue ActiveRecord::UnknownAttributeError, ActiveRecord::RecordInvalid
false
end
end
end
It's easier to write rspec for case update successful. But how to write rspec for case rescue error? It's the reason why we need rspec-mocks.
1. Create fake object
We need to generate an active record error by this way:
let(:user){FactoryGirl.create :user}
let(:unknown_attribute_error){ActiveRecord::UnknownAttributeError.new "", ""}
let(:record_invalid){ActiveRecord::RecordInvalid.new user}
2. Fake object to test method by error case
Use allow(object).to receive(method){value}
to fake object's method's value.
In this case, we need to fake object with error active record, so we can use allow(object).to receive(action).and_raise(error)
.
Finally, we have rspec for example method:
subject{UpdateUserAndSubject.perform user, subject}
it do
allow(user).to receive(:update_attributes!).and_raise(unknown_attribute_error)
is_expected.to eq false
end
it do
allow(user).to receive(:update_attributes!).and_raise(record_invalid)
is_expected.to eq false
end
IV. More about rspec-mocks
- When need to fake more value for method, we use
.and_return
to do it. For example:
allow(user).to receive(:rank).and_return(1, 2, 3)
die.rank # => 1
die.rank # => 2
die.rank # => 3
die.rank # => 3
die.rank # => 3
- When need to fake method with arguments, we use
.with(*args)
afterreceive(method)
. - When need to fake message validate, we use
receive(:validate){"message"}
. - We can fake class method easily:
allow(User).to receive(:find){user}
V. Conclusion
Rspec-mocks is very useful in rspec test. That's some simple case to use rspec-mocks in unit test. Hope that it's useful for someone. Thanks for reading!
All rights reserved