Home > Software design >  Sinon stub - mocking a function which returns an array of objects
Sinon stub - mocking a function which returns an array of objects

Time:10-28

I am trying to stub the following code

async function logUpdate(client) {
  const results = await client.query(query.toParam());
  const { count, timestamp } = results.rows[0];

  await db.updateDatasourceLogs(destdb, DB.src, TABLES.src, timestamp, count);
}

This is the following code i am using to stub the above code

  fakeClient = {
      query: sinon.stub().resolves(fakeRows),
    };

   const rowData = {
      count: 1,
      timestamp: ''
   };

    fakeRows = {
      rows: sinon.stub().returns([rowData]),
    };

   fakeSequel = {
       useFlavour: sinon.stub().returns(toParam: () => false,),
   };

I am getting an error for destructuring

TypeError: Cannot destructure property count of 'undefined' or 'null'.

at line

const { count, timestamp } = results.rows[0];

how to stub the above line?

CodePudding user response:

If we look at the body of your logUpdate function, we see it begins with the following two lines:

const results = await client.query(query.toParam());
const { count, timestamp } = results.rows[0];

This code says:

  1. Await the Promise returned by the call to client.query and assign it to a variable called results.
  2. results is an Object with a property called rows which is an Array whose 0th element should be an Object with count and timestamp properties - which we destructure into local variables.

This implies that the value of results looks like:

{
  "rows": [
    {
      "count": 1
      "timestamp": "0"
    }
  ]
}

However, in our stubbing code, we have the following:

fakeRows = {
  rows: sinon.stub().returns([rowData]),
};

Which says that fakeRows is an Object with a rows property whose value is a function that returns [rowData].

If we were to implement this Object without sinon, it would look like:

{
  "rows": function () {
    return [
      {
        "count": 1
        "timestamp": "0"
      }
    ];
  }
}

Notice the difference between the structure that logUpdate is expecting and what fakeRows actually provides. Specifically, logUpdate expects results to have a rows Array, but, with our stubbed code, it has a rows Function!

We can fix this simply by having fakeRows reference our rowData directly:

const fakeRows = {
  rows: [rowData]
};
  • Related