{"id":12036,"library":"sinon-chai","title":"Sinon-Chai: Sinon.JS Assertions for Chai","description":"Sinon-Chai is a testing utility that integrates the Sinon.JS mocking framework with the Chai assertion library, allowing developers to write more expressive and readable assertions for spies, stubs, and mocks. Instead of using Sinon's direct assertion methods (`sinon.assert.calledWith`) or awkward Chai property checks, Sinon-Chai extends Chai's `should` and `expect` interfaces to provide natural language assertions like `expect(mySpy).to.have.been.calledWith('foo')`. The current stable version is 4.0.1, which supports Chai v5 and v6, and Sinon v4+. The library maintains an active release cadence, typically updating to support new major versions of its peer dependencies, Chai and Sinon. Key differentiators include its seamless integration into the Chai assertion chain, improving test readability and developer experience by providing a unified assertion style across a test suite. It's widely used in JavaScript testing environments for both Node.js and browser applications.","status":"active","version":"4.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/chaijs/sinon-chai","tags":["javascript","chai","chai-plugin","browser","vendor","mocks-and-spies","sinon","testing","spies"],"install":[{"cmd":"npm install sinon-chai","lang":"bash","label":"npm"},{"cmd":"yarn add sinon-chai","lang":"bash","label":"yarn"},{"cmd":"pnpm add sinon-chai","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, Sinon-Chai extends Chai's assertion interface.","package":"chai","optional":false},{"reason":"Peer dependency, Sinon-Chai provides assertions for Sinon's spies, stubs, and mocks.","package":"sinon","optional":false}],"imports":[{"note":"Since v4.0.1, the documentation encourages ESM imports. While CJS might still work, ESM is the recommended approach for modern projects. The default export is the plugin function itself.","wrong":"const sinonChai = require('sinon-chai');","symbol":"sinonChai","correct":"import sinonChai from 'sinon-chai';"},{"note":"The Sinon-Chai plugin is activated by passing it to Chai's `use` method. This needs to happen once at the start of your test suite.","wrong":"chai.use(sinonChai); // if `chai` itself is imported via CJS `require`","symbol":"use (Chai method)","correct":"import { use, expect } from 'chai';\nuse(sinonChai);"},{"note":"To use the `should` assertion style, you must either import `chai/register-should` or call `chai.should()` once. This is a Chai-specific setup, not directly tied to sinon-chai, but crucial for its usage with `should`.","symbol":"should (Chai style)","correct":"import 'chai/register-should'; // or `chai.should()`\n// ... then later:\nmySpy.should.have.been.calledOnce;"}],"quickstart":{"code":"import { expect, use } from 'chai';\nimport * as sinon from 'sinon';\nimport sinonChai from 'sinon-chai';\n\n// Initialize Chai with sinon-chai plugin\nuse(sinonChai);\n\ndescribe('MyService with Sinon-Chai', () => {\n  let mySpy: sinon.SinonSpy;\n\n  beforeEach(() => {\n    // Create a new Sinon spy before each test\n    mySpy = sinon.spy();\n  });\n\n  afterEach(() => {\n    // Restore the spy after each test to prevent side effects\n    mySpy.restore();\n  });\n\n  it('should call the spy once with the expected argument', () => {\n    const serviceMethod = (param: string) => {\n      mySpy(param);\n    };\n\n    serviceMethod('first-call');\n\n    // Use sinon-chai assertions\n    expect(mySpy).to.have.been.calledOnce;\n    expect(mySpy).to.have.been.calledWith('first-call');\n    expect(mySpy).to.not.have.been.calledWith('wrong-argument');\n  });\n\n  it('should not call the spy if a condition is not met', () => {\n    const serviceMethodConditional = (shouldExecute: boolean) => {\n      if (shouldExecute) {\n        mySpy('executed');\n      }\n    };\n\n    serviceMethodConditional(false);\n\n    expect(mySpy).to.not.have.been.called;\n    expect(mySpy).to.have.callCount(0);\n  });\n});","lang":"typescript","description":"This quickstart demonstrates how to set up Sinon-Chai with Chai and Sinon, creating a spy and using `expect` assertions to verify call counts and arguments."},"warnings":[{"fix":"Ensure your project meets the minimum peer dependency requirements for Node.js, Sinon, and Chai before upgrading to `sinon-chai@3.0.0` or higher.","message":"Version 3.0.0 introduced breaking changes, requiring Node.js 4+, Sinon 4+, and Chai 4+.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Check your `package.json` for `chai` and `sinon` versions. `sinon-chai@4.0.x` requires `chai: ^5.0.0 || ^6.0.0` and `sinon: >=4.0.0`.","message":"Version 4.0.0 added support for Chai v5, and 4.0.1 added support for Chai v6. Ensure your Chai version is compatible with your `sinon-chai` version based on the peer dependencies.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Adjust your assertion syntax to `expect(spy).to.always.have.been.calledWith(...)` or `spy.should.always.have.been.calledWith(...)`.","message":"When using `always` assertions (e.g., `alwaysCalledWith`), the `.always` property must be placed directly after `should` or `to` (e.g., `spy.should.always.have.been.calledWith`). Incorrect placement like `spy.should.have.been.alwaysCalledWith` will not work.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"For assertions involving `sinon.match`, integrate `chai-samsam` or perform a direct check on the spy's calls like `expect(mySpy.firstCall.args[0]).to.match(someRegex);`.","message":"Sinon-Chai does not directly provide assertions for `Sinon.assert.match`. If you need to assert against complex argument matching, consider using `chai-samsam` or manual checks.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you have `import { expect, use } from 'chai';` and `use(sinonChai);` at the top of your test file. For the `should` style, also include `import 'chai/register-should';` or call `chai.should();`.","cause":"Chai's assertion interfaces (`should` or `expect`) are not correctly loaded or activated before using Sinon-Chai assertions.","error":"TypeError: Cannot read properties of undefined (reading 'should') OR TypeError: expect is not a function"},{"fix":"Review your test setup and the code under test. Ensure the spy is correctly injected and that the execution path actually triggers the spy. Use `mySpy.getCalls()` or `console.log(mySpy.args)` to inspect the spy's behavior.","cause":"The Sinon spy, stub, or mock was either not invoked, called with different arguments, or the test subject did not behave as expected.","error":"AssertionError: Expected spy to be called once, but it was not. (or similar for `calledWith`, `returned`, etc.)"},{"fix":"Use ESM import syntax: `import sinonChai from 'sinon-chai';`. If your project is CommonJS, you might need to ensure compatibility or check for older versions that explicitly supported CJS without such issues.","cause":"You are attempting to import `sinon-chai` using CommonJS `require()` syntax in a project configured for ESM, or Node.js's module resolution is treating it as an ESM module when your code is CJS.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/sinon-chai/index.js from ... is not supported."}],"ecosystem":"npm"}