Steve Jorgensen:
> when testing classes in isolation, it's hard to be
> sure that the test doubles are in sync with the actual
> objects that the test subject will interact with.
You might be interested in Bogus¹, which fails stubs and mocks
if the test double does not respond to the message you stub/mock
or the message takes a different number of arguments.
Bogus also attempts² to implement contract tests: if tests
for Foo stub/mock an interaction with a collaborator Bar,
you can enforce that tests for Bar actually do exercise the
exact scenario that’s being stubbed/mocked in Foo’s tests.
¹
https://github.com/psyho/bogus
² It’s Still an Experimental Feature™
For stub/mock synchro there’s also rspec-fire³, and
I think this functionality might be rolled into RSpec 3.
³
https://github.com/xaviershay/rspec-fire
> My newest idea is to have a data-like object that can be given
> either simple values or callable objects for its attributes.
> When an attribute is read, if the underlying value is a callable
> (something that responds to #call) then the result of invoking
> #call is returned. Otherwise, the object is returned.
Bogus’s implementation is similar; this seems to work quite well. The
clumsy situation is when you want the stub to return a callable – in
these cases you need to wrap it in an additional callable layer.
> The gem:
https://github.com/stevecj/consensus
I like the idea, but I fear it applies best to greenfield projects
(where you can indeed use it both in tests and code under test)
and might need some more work to be applicable to many real-world
edge cases – but I’m looking forward to how it how it develops!
— Piotr Szotkowski
--
How many seconds are there in a year? If I tell you there are 3.155×10⁷,
you won’t even try to remember it. On the other hand, who could forget
that – to within half a percent – π seconds is a nanocentury.
[Tom Duff]