RSpec Mock Object Example

前端 未结 5 1036
说谎
说谎 2021-01-30 13:13

I am new to mock objects, and I am trying to learn how to use them in RSpec. Can someone please post an example (a hello RSpec Mock object world type example), or a link (or any

5条回答
  •  梦如初夏
    2021-01-30 14:02

    Normally you want to use a Mock Object when you want to delegate some functionality to other object but you don't want to test the real functionality on your current test, so you replace that object with other that is easier to control. Let's call this object "dependency"...

    The thing that you are testing (object/method/function...) can interact with this dependency by calling methods to...

    • Query for something.
    • Change something or produce some side effect.

    When calling a method to query for something

    When you are using the dependency to "query" for something, you don't need to use the "mock API" because you can just use a regular object, and test for the expected output in the object that you are testing... for example:

    describe "Books catalog" do
      class FakeDB
        def initialize(books:)
          @books = books
        end
    
        def fetch_books
          @books
        end
      end
    
      it "has the stored books" do
        db = FakeDB.new(books: ["Principito"])
        catalog = BooksCatalog.new(db)
        expect(catalog.books).to eq ["Principito"]
      end
    end
    

    When calling a method to change something or produce some side effect...

    When you want to make a change in your dependency or do something with side effects like inserting a new record on a database, sending an email, make a payment, etc... now instead of testing that the change or side effect was produced, you just check that you are calling the right function/method with the right attributes... for example:

    describe "Books catalog" do
      class FakeDB
        def self.insert(book)
        end
      end
    
      def db
        FakeDB
      end
    
      it "stores new added books" do
        catalog = BooksCatalog.new(db)
    
        # This is how you can use the Mock API of rspec
        expect(db).to receive(:insert).with("Harry Potter")
    
        catalog.add_book("Harry Potter")
      end
    end
    

    This is a basic example, but you can do a lot just with this knowledge =)

    I wrote a post with this content and a little more that maybe can be useful http://bhserna.com/2018/how-and-when-to-use-mock-objects-with-ruby-and-rspec.html

提交回复
热议问题