Skip to content

Instantly share code, notes, and snippets.

@christroutner
Last active August 28, 2018 00:39
Show Gist options
  • Save christroutner/486155ff99da7fb395026cc08e41b2e6 to your computer and use it in GitHub Desktop.
Save christroutner/486155ff99da7fb395026cc08e41b2e6 to your computer and use it in GitHub Desktop.
Wormholecash Unit Test Template

This gist is an example of how unit tests could be written for the Wormholecash repo. The example below is taken from the balancesForAddress test in the dataRetrieval.js test file.

The original test looks like this:

// This is technically an 'integration' test because it makes a live HTTP call.
describe("#balancesForAddress", () => {
  it(`original (integration) test`, async () => {
    let balancesForAddress = await Wormhole.DataRetrieval.balancesForAddress(
      "bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg"
    );
    //console.log(`balancesForAddress: ${JSON.stringify(balancesForAddress,null,2)}`);
    assert.deepEqual(Object.keys(balancesForAddress[0]), ["propertyid", "balance", "reserved"]);
  });
});

One of the big distinctions between unit and integration tests is that unit tests don't rely on any external services, like a databases or external servers. The test above would be classified as an integration test. Both tests are important, as are end-to-end tests. Ideally, reliable software has all three.

Here are my take on unit tests. While sinon and mockery are great ways to mock out libraries, for http calls, I like to use nock. I use it below to mock out the HTTP calls without having to mock out axios directly.

let chai = require("chai");
let assert = require("assert");
const nock = require("nock");
let wh = require("./../lib/Wormhole").default;
let Wormhole = new wh({
  restURL: "https://wormholecash-staging.herokuapp.com/v1/",
});


describe("#DataRetrieval", () => {

  // This is a 'unit' test because it mocks the http request and requires no external service to run the test.
  it(`unit test`, async () => {
    // https://wormholecash-staging.herokuapp.com/v1/dataRetrieval/balancesForAddress/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg
    nock(`https://wormholecash-staging.herokuapp.com`)
      .get(
        `/v1/dataRetrieval/balancesForAddress/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg`
      )
      .reply(200, [
        {
          propertyid: 1,
          balance: "67.65779501",
          reserved: "0.00000000",
        },
      ]);

    let balancesForAddress = await Wormhole.DataRetrieval.balancesForAddress(
      "bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg"
    );
    assert.deepEqual(Object.keys(balancesForAddress[0]), ["propertyid", "balance", "reserved"]);
  });

  // The advantage of unit tests is that you can respond with a variety of errors,
  // like this 503 HTTP error.
  it(`503 unit test`, async () => {
    // https://wormholecash-staging.herokuapp.com/v1/dataRetrieval/balancesForAddress/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg
    nock(`https://wormholecash-staging.herokuapp.com`)
      .get(
        `/v1/dataRetrieval/balancesForAddress/bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg`
      )
      .reply(503, "error");

    try {
      await Wormhole.DataRetrieval.balancesForAddress(
        "bchtest:qq2j9gp97gm9a6lwvhxc4zu28qvqm0x4j5e72v7ejg"
      );

      assert.equal(false, true, "Test passing unexpectedly!");
    } catch (err) {
      assert.equal(err.response.status, 503, "503 error expected.");
    }
  });
});

It would be good to add a few more test cases to a test like this. Like the ECONNREFUSED error in this issue or returning a rejected promise.

Another way to do these same tests is to use assert.throws(), but there is a strong case to be made in the testing industry for writing positive and negative tests. The last test would be considered a negative test, by putting the assertion in the catch. throws is a fine way to do it too, but I find this format makes the most sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment