Muirik
Muirik

Reputation: 6289

Writing a Mocha unit test for a function that does not explicitly return a value

I have a question about writing a Mocha unit test within my Node app when the function doesn't explicitly return anything.

Specifically, the function I want to write a test for iterates over two arrays -- one for inserts and one for updates. That function looks like this:

module.exports = async function dataSetsMergeOp(args) {
  const recordsToInsert = args.newRecords;
  const recordsToUpdate = args.matchingRecords;

  // Handle inserts
  if (recordsToInsert.length > 0) {
    for (let record of recordsToInsert) {
      try {
        const insertQuery = `
        INSERT INTO cd.customer_accounts (
          hypindx,
          hypnumbr_1,
          hypnumbr_2,
        ) VALUES (?, ?, ?);
        `;
        const args = [
        record.HYPINDX,
        trimmedStringOrNull(record.HYPNUMBR_1),
        trimmedStringOrNull(record.HYPNUMBR_2),
        ];
        console.log('Record inserting...');
        await queryHandler(insertQuery, args);
      } catch (error) {
        console.log(error);
      }
    }
  }

  // Handle updates
  if (recordsToUpdate.length > 0) {
    for (let record of recordsToUpdate) {
      try {
        const updateQuery = `
        UPDATE cd.customer_accounts
        SET
          hypindx = ?,
          hypnumbr_1 = ?,
          hypnumbr_2 = ?
        WHERE hypindx = ?
      `;
      const args = [
        record.ACTINDX,
        trimmedStringOrNull(record.HYPNUMBR_1),
        trimmedStringOrNull(record.HYPNUMBR_2),
        record.HYPINDX
      ];
      console.log('Record updating...');
      await queryHandler(updateQuery, args);
      } catch (error) {
        console.log(error);
      }
    }
  }
};

Now the relevant part of my mocha test would look something like this:

  before(async function () {
    try {
      result = await dataSetsMergeOp(args);
    } catch (e) {
      console.log(e.stack);
    }
  });
  it("should be truthy", function () {
    assert.isOk(result);
  });
  it("should return an object for the 'job'", function () {
    assert.isObject(result);
  });
  it("should return a number for the 'affectedRows' property", function () {
    assert.typeOf(result.affectedRows, "number");
  });
  it("should return a number for the 'warningStatus' property", function () {
    assert.typeOf(result.warningStatus, "number");
  });
  it("expect 'warningStatus' to be 0", function () {
    expect(result.warningStatus).to.equal(0);
  });

But in my case here, because I don't explicitly return anything in the function that's being tested, what result ends up being -- even when the function runs successfully -- is undefined. And because my function utilizes a for-of loop, I don't want to use return await in my dataSetsMergeOp() function because, while that will make the tests pass, it will stop the loop after the first iteration.

So what's the recommended way to write a test for this kind of function?

Upvotes: 0

Views: 1328

Answers (1)

moonwave99
moonwave99

Reputation: 22810

To unit test the function, I would expect that the function throws no exceptions for instance.

You may want to return something like { updatedDocumentsCount: n }, and increment it at every loop iteration, and assert that it equals the number of docs you passed.

For the integration test, you want to query your db before and after the function execution, and to check that you actually updated / inserted the expected number of documents.

Upvotes: 1

Related Questions