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

spyfactory

v0.3.5

Published

Uses sinon and stubcontractor to build fake services that obey contracts and spies on each call.

Downloads

19

Readme

spyFacory

What?

A spy factory creates service fakes within node, that enforce the call contract on methods.

Why?

When testing complicated interactions, sometimes we are stuck testing the interactions between services. The spy factory builds these mock objects.

Note

Touch Integration is the idea that a fake should uphold the contract the original object held. This way if the object undertest is changed such that it now violates that contract, tests will fail and not production.

Spy facory uses stubcontractor to ensure touch intigration.

Note

This library works really well with approval-result-factory


Initialization

Spy Factory needs to be initialized with a stubcontractor that is configured for your project.

const stubcontractor = require('./stubcontractorConfig');
const spyFactory = require('spyfactory')(stubcontractor);

Basic Usage

const fakeObject = spyFactory(
                'myModule',
                [
                    'add'
                ]
            );

This finds a file called 'myModule'. In that file it locates a function called 'add'. It then creates an object that enforces the contract of add.

Add also has a sinon spy to the add method.

this spy can be retrieved by:

const spy = fakeObject.add.getOnCallAction();

Last item of note is the fake object has a property called '__name'. This is by default set to the name given in the first parameter. In this case, 'myModule'.


Adding an action to be performed

const fakeObject = spyFactory(
                'myModule',
                [
                    ['add', function (a, b) { return a + b; }]
                ]
            );

If an array is given instead of a string, the second parameter is a function which will be called each time the method is called.

It is simular to:

const fakeObject = {
    add: sinon.spy(function (a, b) { return a + b; })
};

Except that it will also do touch intigration.


Not spying on a method

const fakeObject = spyFactory(
                'myModule',
                [
                    ['add', (a, b) => a + b, false]
                ]
            );

If you do not want to spy on a function, you can add a third item to the the array. If this item is the boolean false then the function will be faked but without a spy attached. It will however still inforce touch intigration.


renameTo

Sometimes the internal implimentation uses a method who's name does not match what is attached to the object the service exports. Then it is handy to rename that service.

Example

// This is the module the spy is created from.
// adder.js
function addAndThenAddAgain(a, b c) {
    return (a + b + c) * 2;
}

module.exports = {
    addTwice: addAndThenAddAgain
};

To create a fake of the above service:

let adderFake = spyFactory(
    'adder',
    [
        'addAndThenAddAgain'
    ]
);

adderFake.addAndThenAddAgain.renameTo('addTwice');

After renameTo is called, the addAndThenAddAgain is no longer a function on the adderFake. It has been renamed to addTwice.

Call a callback

Spy factory, comes with a nice helper. If your methods conform to the convention that the callback is the last function and the function has the following signature:

(error, data) => undefined

Then spy factory has a tool that will help ensure that the callback is called.

const fakeObject = spyFactory(
                'myModule',
                [
                    ['asyncAdd', spyFactory.callCallback(null, 4)],
                    ['asyncSubtract', spyFactory.callCallback()]
                ]
            );

This creates a function that looks something like this:

function callbackCaller(...args) {
    const callback = args.pop();
    callback(givenError, givenData);
}

Where 'givenError' and 'givenData' are the parameters passed to 'callCallback'.


Call a callback via

This allows the callback to be passed to a function that will call the callback.

let stuffHappend = false;

const fakeObject = spyFactory(
                'myModule',
                [
                    ['asyncAdd', spyFactory.callCallbackVia(callback => callback(null, stuffHappend))],
                ]
            );

Later ..

stuffHappend = true;
fakeObject.asyncAdd((error, data) => {
    if(data) {
        console.log('Got it!');
    }
});

Because stuffHappend is later set to true then the console will log "Got it!".