How to use rspec-mocks
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 ...
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) after receive(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!