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?