I think your issue is that td.object
doesn't work the way you think it does:
td.object(realObject)
- returns a deep imitation of the passed object, where each function is replaced with a test double function named for the property path (e.g. If realObject.invoices.send()
was a function, the returned object would have property invoices.send
set to a test double named '.invoices.send'
)
Source: https://github.com/testdouble/testdouble.js#tdobject
So when you do…
const foo = td.func();
const obj = td.object({foo});
… you're actually mocking foo
twice.
Here's a demo:
const td = require('testdouble');
const num2str = td.func('num->string');
td.when(num2str(42)).thenReturn('forty two');
td.when(num2str(43)).thenReturn('forty three');
td.when(num2str(44)).thenReturn('forty four');
const x = {num2str};
const y = td.object({num2str});
num2str(42);
x.num2str(43);
y.num2str(44);
Then we can inspect x.num2str
and we can see that it is the same test double as num2str
:
td.explain(x.num2str).description;
/*
This test double `num->string` has 3 stubbings and 2 invocations.
Stubbings:
- when called with `(42)`, then return `"forty two"`.
- when called with `(43)`, then return `"forty three"`.
- when called with `(44)`, then return `"forty four"`.
Invocations:
- called with `(42)`.
- called with `(43)`.
*/
However y.num2str
is a completely different test double:
td.explain(y.num2str).description;
/*
This test double `.num2str` has 0 stubbings and 1 invocations.
Invocations:
- called with `(44)`.
*/
I think what you're looking for is the "property replacement" behaviour of td.replace
:
const z = {
str2num: str => parseInt(str),
num2str: num => {
throw new Error('42!');
}
};
td.replace(z, 'num2str');
td.when(z.num2str(42)).thenReturn('FORTY TWO!!');
The z.str2num
function hasn't been mocked:
z.str2num("42");
//=> 42
However z.num2str
is a fully-fledged test double:
z.num2str(42);
//=> 'FORTY TWO!!'
td.explain(z.num2str).description;
/*
This test double `num2str` has 1 stubbings and 1 invocations.
Stubbings:
- when called with `(42)`, then return `"FORTY TWO!!"`.
Invocations:
- called with `(42)`.
*/