How to properly stub a function return value?

2k Views Asked by At

I am attempting to mock the return value for the method of my class and keep receiving this error:

not ok Unsatisfied verification on test double. Wanted: - called with (true). But there were no invocations of the test double.

Here is my testing code:

// Imports for unit testing
const tap = require('tap');
const Subject = require('../src/iTunesClient.js');
const td = require('testdouble');

let reqJson;

// Ensure the iTunes class methods are called
tap.test('iTunesClient class methods function as intended', (t) => {
  t.beforeEach((ready) => {
    reqJson = td.replace('../src/reqJson.js');
    ready();
  });

  t.afterEach((ready) => {
    td.reset();
    ready();
  });

  t.test('iTunesClient.getData', (assert) => {
    const callback = td.function();
    const subject = new Subject();
    subject.setTerm('abc 123');
    subject.setURL();

    td.when(reqJson.get(td.callback)).thenCallback(true);

    subject.getData(callback);

    td.verify(callback(true));
    assert.end();
  });

  t.end();
});

Specifically, this line is related to my issue:

td.verify(callback(true));

How can I fake the callback value of true for reqJson.get()? Right now, Subject.geData() is a method of the iTunesClient class which calls another file, reqJson.js, to use its exported get() method.

2

There are 2 best solutions below

0
On BEST ANSWER

I wanted to update this question, as I recently solved this issue. Essentially, I had two issues:

  1. Account for both reqJson function parameters
  2. Account for all callback return values

Per testdouble documentation for item 1:

When passed td.matchers.anything(), any invocation of that test double function will ignore that parameter when determining whether an invocation satisfies the stubbing.

Hence, I adjusted my line of code as follows:

Before: td.when(reqJson.get(td.callback)).thenCallback(true);

After: td.when(reqJson.get(td.matchers.anything(), td.callback)).thenCallback(null, null, null);

0
On

It's a little hard to tell from your example, but it looks like you're requiring iTunesClient before you call td.replace. In this case, the real reqJson module will be required and cached on line 3.

You need to call td.replace early enough to avoid this, e.g. in between requiring tap and iTunesClient.