npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tape-nock

v1.7.0

Published

Automatically record and playback HTTP calls for each tape test.

Downloads

414

Readme

tape-nock

npm npm-next travis standard Package Quality Coverage Status - Master

Automatically record and playback HTTP calls for each tape test. This package is really just a decorator that wraps each test individual test with nock's Nock Back feature. This helps avoid the all nockBack wrapping code which can make tests less clear.

Install

npm install tape-nock --save-dev

Usage

var path = require('path')
var tape = require('tape') // still need to require tape
var tapeNock = require('tape-nock')

// call tapeNock with tape and an options object
var test = tapeNock(tape, { //options object to be passed to nock, not required
  fixtures: path.join(__dirname, 'fixtures'), // this is the default path
  mode: 'dryrun', // this is the default mode
  defaultTestOptions: { // optionally provide default options to nockBack for each test
    before: function () {
      console.log('a preprocessing function, gets called before nock.define')
    },
    after: function () {
      console.log('a postprocessing function, gets called after nock.define')
    }
  }
})

(see nockBack test options for more information on before, after, and afterRecord functions used in defaultTestOptions)

Now just write your tape tests as usual:

var request = require('request')

test('do it live on the internet', function(t) {
  request.get('https://registry.npmjs.org', function (err, res) {
    t.error(err)
    t.ok(res)
    t.end()
})

in dryrun mode, the above test will go to the internet and nothing will be recorded.

Once your tests are perfected, Create fixture files by using the record mode. This captures all HTTP calls per test and saves it to the fixtures directory.

To record, set the NOCK_BACK_MODE environment variable:

NOCK_BACK_MODE=record npm test

...or do it programatically via the tape-nock options object:

var test = tapeNock(tape, {
  fixtures: path.join(__dirname, 'fixtures'),
  mode: 'record' // record mode!
})

A new file called do it live on the internet.json will be created in the fixtures directory. It will contain an array of HTTP calls that were made during the test. Each test will have its own JSON.

Once a fixture exists for a test, it will be used every time in dryrun mode. To re-record, you'll need to delete the JSON file.

To make this easier, add scripts to your package.json for easy recording/running:

{
  "scripts" {
    "test": "tape test/*js"
    "test:record": "NOCK_BACK_MODE=record npm test",
    "test:wild": "NOCK_BACK_MODE=wild npm test",
    "test:lockdown": "NOCK_BACK_MODE=lockdown npm test",
    "test:overwrite": "rm test/fixtures/*.json & npm run test:record"
  }
}

Can still mock things

It is also possible to manually mock at the same time so a request NEVER hits a URL.

Just get a copy of nock from tape-nock via .nock and use it:

var tape = require('tape')
var tapeNock = require('tape-nock')
var test = tapeNock(tape, {
  fixtures: path.join(__dirname, 'fixtures') //defaults to this path
})

var request = require('request')
test('able to get a copy of nock from test.nock and use it', function (t) {
  // get a copy of nock
  var nock = test.nock

  // use it to mock a URL. This mock will live even if NOCK_BACK_MODE=wild
  nock('http://registry.npmjs.org').get('/clockmoji').reply(200, {'yep': 'it works'})

  request.get('http://registry.npmjs.org/clockmoji', process)

  function process (err, resp) {
    t.error(err, 'no error')
    t.equals(JSON.parse(resp.body).yep, 'it works', 'able to mock directly with nock instance')
    t.end()
  }
})

NOCK_BACK_MODE

Use the NOCK_BACK_MODE environment variable (details) to control the mode of nockBack.

Here is a recap

  • wild: all requests go out to the internet, don't replay anything, doesn't record anything
  • dryrun: The default, use recorded nocks, allow http calls, doesn't record anything, useful for writing new tests
  • record: use recorded nocks, record new nocks
  • lockdown: use recorded nocks, disables all http calls even when not nocked, doesn't record

Nock Back options

Its also possible to pass nockBack options through tape's options object.

This is helpful for doing filteringPath or filteringRequestBody (check out the PROTIP... that can be done in an "after" function).

For Example, this test will use the after function passed in, which will make all "time-based-param" params in the path and replace them with 123. This will ensure time-based parameters will still be mock-able (the path in the fixture JSON will need to be manually updated to match).

var after = function (scope) {
  scope.filteringPath(/time-based-param=[^&]*/g, 'time-based-param=123')
}

test('pass through opts to nockback', {after: after}, function (t) {
  request.get('http://registry.npmjs.com?time-based-param=1455231758348', function (err, resp) {
    t.error(err)
    t.equals(JSON.parse(resp.body).haha, 'no secrets for you', 'secrets are protected')
    t.end()
  })
})

Using supertest with tape-nock

Since nockBack will mock all HTTP requests, using supertest can be tricky. Here is an example of how to avoid mocking/recording local connections when using supertest.

Here is our application. It simply hits http://httpbin.org/get which echos info back. We want to have nockBack record/mock the httpbin request but still allow supertest http requests to 127.0.0.1 to pass through for all tests. This is done by leveraging the defaultTestOptions.

app.js

const express = require('express')
const request = require('superagent')

var app = express()

app.get('/myapp/version', function (req, res) {
  superagent
    .get('http://httpbin.org/get')
    .end(function (err, response) {
      res.status(200).json({
        version: '0.1.0',
        url: response.body.url
      })
    })
})

module.exports = app

test.js

const supertest = require('supertest');
const app = require('../app.js');

const tape = require('tape');
const tapeNock = require('tape-nock');
const nock = tapeNock.nock;

const opts = {
  // after recording the fixtures, remove any scopes that hit 127.0.0.1
  // this is not necessary with our before function below, but it makes it a bit cleaner.
  afterRecord: function (scopes) {
    var localhost = /http:\/\/127\.0\.0\.1.*/;
    scopes = scopes.filter(function (s) {
      return !localhost.test(s.scope);
    });

    return scopes;
  },
  before: function () {
    // allow connections to 127.0.0.1 even when NOCK_BACK_MODE=lockdown
    nock.enableNetConnect('127.0.0.1');
  }
};

// call tapeNock with tape and an options object
const test = tapeNock(tape, { defaultTestOptions: opts });

// note that we're passing in test.options here
// which has our special "afterRecord" and "before" functions
test('hit version url', function (t) {
  supertest(app)
    .get('/myapp/version')
    .expect(200, {
      url: 'http://httpbin.org/get',
      version: '0.1.0'
    })
    .end(function (err, res) {
      t.error(err, 'no error');
      t.equals(res.body.url, 'http://httpbin.org/get', 'url is correct');
      t.end();
    });
});

Contributing

Contributions welcome! Please read the contributing guidelines first.

License

ISC