+5

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

  • 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!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí