
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
sinon-chai
Advanced tools
The sinon-chai npm package is an extension for the Chai assertion library that provides a set of custom assertions for Sinon.js spies, stubs, and mocks. It allows for more readable and expressive tests by integrating Sinon.js functionalities directly into Chai's BDD/TDD assertion styles.
Assert a spy was called
This feature allows you to assert that a Sinon.js spy was called. The code sample demonstrates how to create a spy on a method and then assert that the method was called using Chai's expect syntax.
const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);
const expect = chai.expect;
const myObj = {
myMethod: function() {}
};
const spy = sinon.spy(myObj, 'myMethod');
myObj.myMethod();
expect(spy).to.have.been.called;
Assert a spy was called with specific arguments
This feature allows you to assert that a Sinon.js spy was called with specific arguments. The code sample demonstrates how to create a spy on a method and then assert that the method was called with a specific argument using Chai's expect syntax.
const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);
const expect = chai.expect;
const myObj = {
myMethod: function(arg) {}
};
const spy = sinon.spy(myObj, 'myMethod');
myObj.myMethod('test');
expect(spy).to.have.been.calledWith('test');
Assert a stub was called a specific number of times
This feature allows you to assert that a Sinon.js stub was called a specific number of times. The code sample demonstrates how to create a stub on a method and then assert that the method was called twice using Chai's expect syntax.
const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);
const expect = chai.expect;
const myObj = {
myMethod: function() {}
};
const stub = sinon.stub(myObj, 'myMethod');
myObj.myMethod();
myObj.myMethod();
expect(stub).to.have.been.calledTwice;
chai-spies is a plugin for the Chai assertion library that provides a set of custom assertions for spies. It offers similar functionalities to sinon-chai but is focused solely on spies, without the additional features for stubs and mocks that sinon-chai provides.
Jest is a JavaScript testing framework that comes with built-in support for spies, stubs, and mocks. It provides a comprehensive testing solution, including a test runner, assertion library, and mocking capabilities. Unlike sinon-chai, Jest is a standalone framework and does not require additional plugins for spying, stubbing, or mocking.
proxyquire is a module used to mock dependencies in Node.js. It allows you to override dependencies during testing, similar to how Sinon.js stubs work. While it does not integrate directly with Chai like sinon-chai, it provides powerful mocking capabilities that can be used alongside Chai for testing.
Sinon–Chai provides a set of custom assertions for using the Sinon.JS spy, stub, and mocking framework with the Chai assertion library. You get all the benefits of Chai with all the powerful tools of Sinon.JS.
Instead of using Sinon.JS's assertions:
sinon.assert.calledWith(mySpy, "foo");
or awkwardly trying to use Chai's should
or expect
interfaces on spy properties:
mySpy.calledWith("foo").should.be.ok;
expect(mySpy.calledWith("foo")).to.be.ok;
you can say
mySpy.should.have.been.calledWith("foo");
expect(mySpy).to.have.been.calledWith("foo");
All of your favorite Sinon.JS assertions made their way into Sinon–Chai. We show the should
syntax here; the expect
equivalent is also available.
Sinon.JS property/method | Sinon–Chai assertion |
---|---|
called | spy.should.have.been.called |
callCount | spy.should.have.callCount(n) |
calledOnce | spy.should.have.been.calledOnce |
calledTwice | spy.should.have.been.calledTwice |
calledThrice | spy.should.have.been.calledThrice |
calledBefore | spy1.should.have.been.calledBefore(spy2) |
calledAfter | spy1.should.have.been.calledAfter(spy2) |
calledImmediatelyBefore | spy.should.have.been.calledImmediatelyBefore(spy2) |
calledImmediatelyAfter | spy.should.have.been.calledImmediatelyAfter(spy2) |
calledWithNew | spy.should.have.been.calledWithNew |
alwaysCalledWithNew | spy.should.always.have.been.calledWithNew |
calledOn | spy.should.have.been.calledOn(context) |
alwaysCalledOn | spy.should.always.have.been.calledOn(context) |
calledWith | spy.should.have.been.calledWith(...args) |
alwaysCalledWith | spy.should.always.have.been.calledWith(...args) |
calledOnceWith | spy.should.always.have.been.calledOnceWith(...args) |
calledWithExactly | spy.should.have.been.calledWithExactly(...args) |
alwaysCalledWithExactly | spy.should.always.have.been.calledWithExactly(...args) |
calledOnceWithExactly | spy.should.always.have.been.calledOnceWithExactly(...args) |
calledWithMatch | spy.should.have.been.calledWithMatch(...args) |
alwaysCalledWithMatch | spy.should.always.have.been.calledWithMatch(...args) |
returned | spy.should.have.returned(returnVal) |
alwaysReturned | spy.should.have.always.returned(returnVal) |
threw | spy.should.have.thrown(errorObjOrErrorTypeStringOrNothing) |
alwaysThrew | spy.should.have.always.thrown(errorObjOrErrorTypeStringOrNothing) |
For more information on the behavior of each assertion, see the documentation for the corresponding spy methods. These of course work on not only spies, but individual spy calls, stubs, and mocks as well.
Note that you can negate any assertion with Chai's .not
. E. g. for notCalled
use spy.should.have.not.been.called
. Similarly, note that the always
methods are accessed with Chai's .always
prefix; should.have.been.alwaysCalledWith
will not work - instead, use should.always.have.been.calledWith
.
For simplicity, this library intentionally only implements Sinon's spy methods, and does not add an interface for Sinon.assert.match
. Sinon's matchers are implemented by the samsam
library, so if you want a should/expect interface to assert.match
you may be interested in chai-samsam, which adds a .deep.match
verb that will work with Sinon matchers.
For assert
interface there is no need for sinon-chai
or chai-samsam
. You can install Sinon.JS assertions right into Chai's assert
object with expose
:
import * as chai from "chai";
import sinon from "sinon";
sinon.assert.expose(chai.assert, { prefix: "" });
Using Chai's should
:
"use strict";
import * as chai from "chai";
import sinon from "sinon";
import sinonChai from "sinon-chai";
chai.should();
chai.use(sinonChai);
function hello(name, cb) {
cb("hello " + name);
}
describe("hello", function () {
it("should call callback with correct greeting", function () {
var cb = sinon.spy();
hello("foo", cb);
cb.should.have.been.calledWith("hello foo");
});
});
Using Chai's expect
:
"use strict";
import * as chai from "chai";
import sinon from "sinon";
import sinonChai from "sinon-chai";
const expect = chai.expect;
chai.use(sinonChai);
function hello(name, cb) {
cb("hello " + name);
}
describe("hello", function () {
it("should call callback with correct greeting", function () {
var cb = sinon.spy();
hello("foo", cb);
expect(cb).to.have.been.calledWith("hello foo");
});
});
Do an npm install --save-dev sinon-chai
to get up and running. Then:
import * as chai from "chai";
import sinonChai from "sinon-chai";
chai.use(sinonChai);
You can of course put this code in a common test fixture file; for an example using Mocha, see the Sinon–Chai tests themselves.
Thanks to Cymen Vig, there's now a Ruby gem of Sinon–Chai that integrates it with the Rails asset pipeline!
FAQs
Extends Chai with assertions for the Sinon.JS mocking framework.
The npm package sinon-chai receives a total of 529,695 weekly downloads. As such, sinon-chai popularity was classified as popular.
We found that sinon-chai demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.