0

I am trying to use mocha and sinon to test a piece of code that is using an AWS service. Below the code:

exports.init = ({ athenaClient }) => {
  const command = {};
  command.execute = sqlCommand => {
    const params = {
      QueryString: sqlCommand,
      QueryExecutionContext: {
        Database: process.env.ATHENA_DB || "default"
      }
    };
    return athenaClient.startQueryExecution(params).promise();
  };

  return command;
};

In my test, I am mocking the athena client and injecting it into the function, and I want to test that the method startQueryExecution is called with the sqlCommand that is sent as an input. So i've been trying to create an stub on it.

This is my test:

const AWS = require("aws-sdk");
const AWS_MOCK = require("aws-sdk-mock");
const sinon = require("sinon");
const expect = require("chai").expect;

describe("Executes a sql command in Athena", async done => {
  process.env.ATHENA_DB = "default";

  it("the sqlCommand is sent to startQueryExecution", async () => {
    const SQL_COMMAND = "DROP TABLE IF EXISTS dataset_test PURGE;";

    const athenaClient = {
      startQueryExecution: params => ({})
    };

    const executeAthenaQueryCommand = require("../commands/executeAthenaQueryCommand").init(
      {
        athenaClient
      }
    );

    sinon.stub(athenaClient, "startQueryExecution");
    sinon.stub(executeAthenaQueryCommand, "execute");

    const result = await executeAthenaQueryCommand.execute(SQL_COMMAND);

    sinon.assert.calledWith(executeAthenaQueryCommand.execute, SQL_COMMAND);

    const expectedResult = {
      QueryString: SQL_COMMAND,
      QueryExecutionContext: {
        Database: "default"
      }
    };

    sinon.assert.calledWith(athenaClient.startQueryExecution, expectedResult);
  });

  after(() => {});
});

However I am getting the error:

   AssertError: expected startQueryExecution to be called with arguments 
    at Object.fail (node_modules/sinon/lib/sinon/assert.js:104:21)
    at failAssertion (node_modules/sinon/lib/sinon/assert.js:61:16)
    at Object.assert.(anonymous function) [as calledWith] (node_modules/sinon/lib/sinon/assert.js:86:13)
    at Context.it (test/executeAthenaQueryCommand.spec.js:37:22)
    at <anonymous>

Any help please?

1
  • You are stubbing the execute method, but not specifying what it should return/resolve. It seems you may not want to stub execute if it is doing a bit of processing create an argument to send to startQueryExecution Commented Feb 22, 2019 at 15:12

1 Answer 1

1

You almost made it correct. Some notes to rectify the test is

Add return in startQueryExecution stub

This is a must so execute function is executed correctly to return promise.

sinon.stub(athenaClient, "startQueryExecution").returns({ promise: () => Promise.resolve() });

Remove stub for execute method

This is real method that we want to test and we call it in the subsequent line so we mustn't stub it.

sinon.stub(executeAthenaQueryCommand, "execute"); // remove this
sinon.assert.calledWith(executeAthenaQueryCommand.execute, SQL_COMMAND); // remove this

So the final test file will be

describe("Executes a sql command in Athena", async done => {
  ...

  it("the sqlCommand is sent to startQueryExecution", async () => {
    ...

    sinon.stub(athenaClient, "startQueryExecution").returns({ promise: () => Promise.resolve() }); // add returns

    const result = await executeAthenaQueryCommand.execute(SQL_COMMAND);

    const expectedResult = {
      QueryString: SQL_COMMAND,
      QueryExecutionContext: {
        Database: "default"
      }
    };

    sinon.assert.calledWith(athenaClient.startQueryExecution, expectedResult);
  });

  after(() => {});
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.