Reputation: 189
There is enough questions
which are related to this topic, but none provide practial
example citing the difference.
According to Fowler's article mocks are not stubs, stubs are fake methods independent from outside calls, while mocks are fake objects with pre-programmed reactions to calls.
Stub's can't make your test fail, but Mocks can.
Mocking is more specific and object-related: if certain parameters are passed, then the object returns certain results. The behavior of an object is imitated or "mocked".
Stubbing is more general and method-related: a stubbed method usually returns always the same result for all parameters. The behavior of a method is frozen, canned or "stubbed".
Let's take a simple test
case. We have to find a Book
provided with id and related to user.
it "can find an Book that this user belongs to" do
project = Book.find( id: '22', email: [email protected] )
expect(project) to eq(some_data);
end
In the above case... What is stub and What is mock? If my example is not valid, can anyone show me example
of Mock and stub.
Upvotes: 2
Views: 1604
Reputation: 115521
Lets get two examples:
let(:email) { 'email' }
# object created from scratch
let(:mocked_book) { instance_double Book, email: email }
it 'check mock' do
expect(mocked_book.email).to eq email
end
#
let(:book) { Book.new }
it 'check stub' do
allow(book).to receive(:email) { email }
expect(book.email).to eq email
end
Your example is not that relevant: you wouldnt test active record, but you could need to stub
it to return a mock
Say you need to test a book receives a method, something like:
def destroy
@book = Book.find(params[:id])
if @book.destroyable?
@book.destroy
else
flash[:error] = "errr"
end
redirect_to books_path
end
You could test with this code:
it 'is not destroyed if not destroyable' do
mocked_book = double 'book', destroyable?: false
allow(Book).to receive(:find).and_return mocked_book
expect(mocked_book).to_not receive :destroy
# here goes the code to trigger the controller action
end
it 'is destroyed if destroyable' do
mocked_book = double 'book', destroyable?: true
allow(Book).to receive(:find).and_return mocked_book
expect(mocked_book).to receive :destroy
# here goes the code to trigger the controller action
end
You can see pros and cons here:
cons: mocks must know exactly what are the expected methods
pros: with mocks you dont need to really create an object and set it up to make it fit some conditions
Upvotes: 1