A spy that can be passed to ruby code, and describe what kind of interfaces it expects.
In languages that use a fair amount of duck-typing (e.g. Ruby), it's nice to know exactly what duck a method expects (i.e. it's implicit interface).
The hope is that the "duck spy" will touch certain paths of code to, at least, make these interfaces somewhat more evident.
A DuckSpy
tells you what methods (and what arguments) have been called.
spy = DuckSpy.new
spy.foo(42)
spy.calls
Returns:
{
:foo => {
:args => [
42
],
:result_duck => {}
}
}
A DuckSpy
can also tell you what interface it expects its result to be able to fulfil.
spy = DuckSpy.new
spy.foo.baz(:some, 'args')
spy.calls
Returns:
{
:foo => {
:args => [],
:result_duck => {
:baz => {
:args => [
:some,
"args"
],
:result_duck => {}
}
}
}
}
A DuckSpy
's behavior can be stubbed one of two ways:
spy = DuckSpy.new
spy.behave_like(a: 35, b: 7)
spy.a + spy.b # => 42
Or, lazily:
spy = DuckSpy.new
spy.stub(:add) { |a, b| a + b }
spy.add(35, 7) # => 42