d1dksg

Safe stubbing with bogus

In isolated tests in Ruby mocked interfaces may misalign with real ones while codebase grows. It can be avoided by using mocks that verify method definitions and fakes that keep those interfaces in sync.

Let's say we start with a repository class with a following store method:

def store(name)
end

And a controller that uses it:

def create(params)
  repository.store(params[:name])
end

We can test the interaction between them using rr:

it 'stores resources' do
  repository = stub
  mock(repository).store('Penguin') { nil }

  controller = Controller.new(repository)

  controller.create(name: 'Penguin')
end

After a while, we need to store the description as well:

def store(name, description)
end

However the controller test still passes while it is incorrect, because it doesn't know anything about repository interface. It can be easily fixed with Bogus by using fakes.

it 'saves images' do
  repository = fake(:repository)
  mock(repository).store('Penguin') { nil }

  controller = Controller.new(repository)

  controller.create(name: 'Penguin')
end

Now this tests fails with ArgumentError: tried to stub store(name, description) with 1 arguments which points us directly to the source of the problem.

Behind the scenes Bogus creates fakes by copying the public interface of repository, it adds mocking syntax that mimics the rr and verifies methods existence and arity.

You can find bogus on github and more details in documentation. Examples from this post are here.

Sign in or sign up to add your response.

2 Responses

6428
Kris avatar

Is this the same as a spie?

over 1 year ago ·
6434
418b0a31e12a61df6a817a17f4f1d827

Do you mean spy? If so, Bogus supports spies as well, actually that is the recommended way of testing with it.

In spy mock objectes are created as doubles of given class, which breaks to rule mock roles not objects. In bogus fakes are identified by a symbol, which by convention points to the camelized class, but it can be configured to any other class or even a 'lowest common interface'.

Another feature that differenties Bogus from rspec-fire or spy are contract test. They make sure that objects tested in isolation can be integrated with each other without any integration tests. However, it is still an experimental part.

over 1 year ago ·
Featured Programming Job

Linux Software/Driver Developer
·
Gdańsk, Poland
·
Full Time
Search all programming jobs