spyfactory

0.3.5 • Public • Published

spyFacory

NPM Version NPM Downloads License MIT Dependencies

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!".

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 0.3.5
    5
    • latest

Version History

Package Sidebar

Install

npm i spyfactory

Weekly Downloads

5

Version

0.3.5

License

MIT

Unpacked Size

23.9 kB

Total Files

20

Last publish

Collaborators

  • jasonkerney