How to test a privately-scoped or anonymous function?

62 Views Asked by At

Imagine I have the following modules:

foo.js

module.exports = function (x, f) {
  f(x);
};

bar.js

const foo = require('./foo');

module.exports = function () {
  foo(40, n => n + 2);
  //      ^
  //      f — How can I test this lambda?
};

I only need to assert that when bar is called, foo is called exactly as shown above ^

I can test that foo has been called with 40 as follow:

const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');

bar();

td.verify(foo(40, td.matchers.anything())); // Pass

But how can I verify that the function f is a function that takes a number, adds 2 to it and returns the result?

PS: I am acutely aware that this isn't exactly testing best practices 101. I would rather not test in this way if I had the opportunity to do things differently. So please humor me.

1

There are 1 best solutions below

0
On

I found two ways:

td.matchers.argThat

This matcher takes a predicate that takes the value of its positional parameter:

const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');

bar();

td.verify(foo(40, td.matchers.argThat(f => f(40) === 42))); // Pass

td.matchers.captor

There is a special matcher called a captor that captures its positional parameter and makes it available later on via the .value property of the matcher:

const tap = require('tap');
const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');
const f = td.matchers.captor();

bar();

td.verify(foo(40, f.capture()));

tap.equal(f.value(40), 42); // Pass
tap.equal(f.value(50), 52); // Pass
tap.equal(f.value(60), 62); // Pass