rogerxu / rogerxu.github.io

Roger Xu's Blog
3 stars 2 forks source link

Sinon #109

Open rogerxu opened 7 years ago

rogerxu commented 7 years ago

Sinon.JS - Standalone test spies, stubs and mocks for JavaScript. Works with any unit testing framework.

rogerxu commented 7 years ago

Spies

Spies - Sinon.JS

A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. There are two types of spies: Some are anonymous functions, while others wrap methods that already exist in the system under test.

var callback = sinon.spy();
var spy = sinon.spy(jQuery, "ajax");
jQuery.ajax.restore();
rogerxu commented 7 years ago

Stubs

Stubs - Sinon.JS

Test stubs are functions (spies) with pre-programmed behavior.

stub.withArgs(42).returns(1);
stub.withArgs(1).throws('TypeError');

Callback

Automatically Invoke

Causes the stub to call the argument at the provided index as a callback function.

stub.callsArg(index);
stub.callsArgOn(index, context);
stub.callsArgWith(index, arg1, arg2, ...);
stub.callsArgOnWith(index, context, arg1, arg2, ...);

Causes the stub to call the first callback it receives with the provided arguments (if any).

stub.yields([arg1, arg2, ...]);
stub.yieldsOn(context, [arg1, arg2, ...]);

// invoke a callback passed as a property of an object
stub.yieldsTo(property, [arg1, arg2, ...]);
stub.yieldsToOn(property, context, [arg1, arg2, ...]);

Manually Invoke

Invoke callbacks passed to the stub with the given arguments.

stub.yield([arg1, arg2, ...]);

// invoke callbacks passed as a property of an object
stub.yieldTo(property, [arg1, arg2, ...]);

function example() {
    var callback = sinon.stub();
    callback({
        "success": function () {
            console.log("Success!");
        },
        "failure": function () {
            console.log("Oh noes!");
        }
    });

    callback.yieldTo("failure"); // Logs "Oh noes!"
}
stub.callArg(argNum);
stub.callArgWith(argNum, [arg1, arg2, ...]);

function example() {
    var callback = sinon.stub();
    callback(function () {
        console.log("Success!");
    }, function () {
        console.log("Oh noes!");
    });

    callback.callArg(1); // Logs "Oh noes!"
}

Constructor

sinon.createStubInstance(constructor);

Invoke

Since sinon@2.0.0

Makes the stub call the provided fakeFunction when invoked.

stub.withArgs(2, 2).callsFake(function foo() {
    return 'bar';
});

Causes the original method wrapped into the stub to be called when none of the conditional stubs are matched.

stub.callThrough();

Call

rogerxu commented 7 years ago

Mocks

Mocks - Sinon.JS

Mocks (and mock expectations) are fake methods (like spies) with pre-programmed behavior (like stubs) as well as pre-programmed expectations.

A mock will fail your test if it is not used as expected.

rogerxu commented 7 years ago

Fake Timers

rogerxu commented 7 years ago

Fake Request

rogerxu commented 7 years ago

Matchers

Matchers - Sinon.JS

Matchers can be passed as arguments to spy.calledOn, spy.calledWith, spy.returned and the corresponding sinon.assert functions as well as spy.withArgs. Matchers allow to be either more fuzzy or more specific about the expected value.

stub.withArgs(sinon.match.string).returns(true);
rogerxu commented 7 years ago

Sandboxes

Sandboxes - Sinon.JS

Sandboxes removes the need to keep track of every fake created, which greatly simplifies cleanup.

var sinon = require('sinon');

var myAPI = { myMethod: function () {} };
var sandbox = sinon.sandbox.create();

describe('myAPI.hello method', function () {

    beforeEach(function () {
        // stub out the `hello` method
        sandbox.stub(myApi, 'hello');
    });

    afterEach(function () {
        // completely restore all fakes created through the sandbox
        sandbox.restore();
    });

    it('should be called once', function () {
        myAPI.hello();
        sinon.assert.calledOnce(myAPI.hello);
    });

    it('should be called twice', function () {
        myAPI.hello();
        myAPI.hello();
        sinon.assert.calledTwice(myAPI.hello);
    });
});
rogerxu commented 7 years ago

JavaScript Testing Tool Showdown: Sinon.js vs testdouble.js — SitePoint

rogerxu commented 7 years ago

Assertions

// call count
spy.callCount
spy.called
spy.notCalled
spy.calledOnce
spy.calledTwice
spy.calledThrice

// call instance
spy.firstCall
spy.secondCall
spy.thirdCall
spy.lastCall
spy.getCall(n)

spyCall.thisValue
spyCall.args
spyCall.exception
spyCall.returnValue

// call behavior
spy.calledOn(obj)
spy.calledWith(arg1, arg2, ...)
spy.calledWithNew()
spy.threw()
spy.returned(obj)