3

I'm a little confused about what makes a test a stub test or a mock test in Rspec. I think it would be best to start with some definitions:

  • A double is just a dummy object that is used as a stand in for other objects that we are testing.

    dummy = double("dummy")
    
  • A stub is a fake object that returns a predetermined value for a method call without calling the actual method on an actual object. An example:

    allow(test).to receive(:foo).and_return("bar")
    
  • But a mock, in addition to returning a fake value, sets a testable expectation that the method being replaced will actually be called in the test. In every other sense, it‘s the same as a stub. An example:

    expect(test).to receive(:foo).and_return("bar")
    

    And if we don‘t call the method test.foo in our test, it will return a test failure.

What makes a test a stub test or a mock test? By just looking at the syntax, they look almost the same:

allow(test).to receive(:foo).and_return("bar")
expect(test).to receive(:foo).and_return("bar")

The only difference that I see is that a stub starts with an allow method, and the mock starts with an expect method. But, I‘ve seen developers use the expect method also in stub tests, just like this one:

project = Project.new(name: "Project Greenlight")
allow(project).to receive(:name).and_return("Fred")
expect(project.name).to eq("Fred")

If I use allow(foo).to receive(:bar), it makes a test a stub test, but when I use expect(foo).to receive(:bar) syntax construction, it makes a test a mock test?

Tomislav Mikulin
  • 5,306
  • 4
  • 23
  • 36
  • 2
    You are right. I was recently confused regarding same too. Mock is a real world situation where you expect something to happen and return; whereas stub is faking a call for a predefined outcome. It might or might not be invoked during the test course. – kiddorails Apr 16 '16 at 12:22
  • 1
    I had a [similar question](http://stackoverflow.com/q/28006913/567863) and received a great answer, so hopefully it serves as a reference for you. – Paul Fioravanti Apr 17 '16 at 00:29
  • Tnx guys for your input. There is just one thing I don't get. The method "expect" doesn't always produce a "mock". As I understand it it produces a mock when it's used with the expect(foo).to **receive(:bar)**.and_return("Jack"). But what puzzels me, is that sometimes the "expect" method is just used for checking values, like in this example: expect(thing.name).to eq("Jack"). This last example isn't a mock its just used as checking the values from the method call. So my question is, that a "mock" is created when we just use the expect(x).to **receive(:y)** syntax? Tnx Tom – Tomislav Mikulin Apr 22 '16 at 16:48

0 Answers0