{"id":13122,"library":"ember-sinon-qunit","title":"Ember Sinon QUnit","description":"Ember Sinon QUnit is an Ember addon that seamlessly integrates the Sinon.js mocking and spying library with QUnit, specifically for Ember applications. Its primary function is to provide automatic cleanup of Sinon's state (spies, stubs, mocks) between individual QUnit tests, preventing leaks and ensuring test isolation. The current stable version is 7.5.0, with frequent updates driven by new Ember and Sinon releases, as seen in recent enhancements for Ember 5 and Sinon v18 support. A key differentiator is its hands-off management of Sinon sandboxes, removing the boilerplate of manual `sinon.restore()` calls, a common footgun when using Sinon directly with QUnit. It supports modern Ember versions (4.12+) and is compatible with Embroider and ember-auto-import v2, consolidating functionality previously spread across several related Ember Sinon addons.","status":"active","version":"7.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/elwayman02/ember-sinon-qunit","tags":["javascript","ember-addon","sinon","qunit"],"install":[{"cmd":"npm install ember-sinon-qunit","lang":"bash","label":"npm"},{"cmd":"yarn add ember-sinon-qunit","lang":"bash","label":"yarn"},{"cmd":"pnpm add ember-sinon-qunit","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, required for Ember application context. Requires >=3.28.0 (v7.0.0 breaking change to >=4.0).","package":"ember-source","optional":false},{"reason":"Peer dependency, the underlying testing framework. Requires ^2.0.0.","package":"qunit","optional":false},{"reason":"Peer dependency, the core mocking library. Requires >=15.0.3 (v7.0.0 breaking change to v15+, updated to v18+ in 7.5.0).","package":"sinon","optional":false}],"imports":[{"note":"This is the primary function to call in your `test-helper.js` to enable automatic Sinon integration and cleanup. It's an ESM default export.","wrong":"const setupSinon = require('ember-sinon-qunit');","symbol":"setupSinon","correct":"import setupSinon from 'ember-sinon-qunit';"},{"note":"The Sinon object itself is imported directly from the `sinon` package into your test files for creating spies, stubs, and mocks. `ember-sinon-qunit` ensures its state is reset per test.","symbol":"sinon","correct":"import sinon from 'sinon';"}],"quickstart":{"code":"import { setApplication } from '@ember/test-helpers';\nimport { start } from 'ember-qunit';\nimport Application from '../app';\nimport config from '../config/environment';\nimport setupSinon from 'ember-sinon-qunit';\nimport { module, test } from 'qunit';\nimport sinon from 'sinon';\n\nsetApplication(Application.create(config.APP));\nsetupSinon();\nstart();\n\nmodule('Example test', function (hooks) {\n  let myService;\n\n  hooks.beforeEach(function() {\n    // Assume myService is instantiated here or injected\n    myService = {\n      doSomething: () => 'original',\n      @action someAction() { return 'action original'; }\n    };\n    this.testStub = sinon.stub(myService, 'doSomething').returns('stubbed');\n  });\n\n  test('sinon is wired up correctly', function (assert) {\n    assert.equal(myService.doSomething(), 'stubbed', 'stub returns stubbed value');\n    assert.ok(this.testStub.calledOnce, 'stub was called once');\n  });\n\n  test('sinon state restored after every test run', function (assert) {\n    assert.notOk(this.testStub.called, 'stub cleaned up after each test run');\n    assert.equal(myService.doSomething(), 'original', 'method is restored');\n\n    // Example of stubbing an @action method\n    let stubAction = sinon.stub(myService, 'someAction').get(() => null);\n    myService.someAction();\n    assert.ok(stubAction.get.calledOnce, '@action stub getter was called');\n  });\n});","lang":"javascript","description":"This quickstart demonstrates how to integrate `ember-sinon-qunit` by calling `setupSinon()` in `test-helper.js` and then shows basic usage of `sinon` within QUnit tests, including automatic cleanup and a common pattern for stubbing `@action` decorators."},"warnings":[{"fix":"Ensure `sinon` is installed as a peer dependency (`yarn add -D sinon`) and meets the version requirement (v15+), and your Ember.js application is running at least version 4.0. Update your `test-helper.js` to use `import setupSinon from 'ember-sinon-qunit';` and remove any legacy `ember-sinon` configurations.","message":"Version 7.0.0 introduced significant breaking changes. It dropped the `ember-sinon` dependency, moved to `ember-auto-import` for bundle integration, and strictly requires `sinon` version 15 or higher, as well as Ember.js v4.0 or higher (specifically documented v4.12+ for full compatibility).","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Always run `yarn add -D sinon` or `npm install --save-dev sinon` after installing `ember-sinon-qunit` to ensure the core Sinon library is available in your project.","message":"Sinon is a peer dependency. Forgetting to install `sinon` explicitly will lead to runtime errors, even after installing `ember-sinon-qunit`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use the `.get()` modifier with `sinon.stub` or `sinon.spy` when targeting `@action` decorated methods. For example: `sinon.stub(service, 'methodToStub').get(() => null);` or `sinon.spy(service, 'methodToStub', ['get']);`","message":"When stubbing or spying on methods decorated with Ember's `@action`, you must treat them as properties rather than direct methods. The `@action` decorator wraps the method in a property getter.","severity":"gotcha","affected_versions":">=7.0.0"},{"fix":"Upgrade to version 7.1.4 or higher to ensure correct TypeScript typings are available and properly referenced in `package.json`.","message":"Initial TypeScript declaration files had issues with incorrect paths or missing exports, particularly for `setupSinon` and the root declaration file.","severity":"breaking","affected_versions":"7.1.0 - 7.1.3"},{"fix":"Trust the addon for automatic cleanup. Avoid manually creating or restoring Sinon sandboxes within tests that use `ember-sinon-qunit`, as it handles this for you. Simply import `sinon` and use it directly; the cleanup will be managed automatically.","message":"The addon provides automatic cleanup of `sinon`'s state between tests. While this is a feature, users accustomed to manual `sinon.sandbox.create()` and `sandbox.restore()` might inadvertently introduce their own manual cleanup, which is unnecessary and can potentially conflict.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `import sinon from 'sinon';` is at the top of your test file and that `sinon` is installed as a peer dependency: `yarn add -D sinon`.","cause":"`sinon` is not correctly imported or installed.","error":"TypeError: Cannot read properties of undefined (reading 'stub')"},{"fix":"Add `import setupSinon from 'ember-sinon-qunit';` and `setupSinon();` to your `tests/test-helper.js` file.","cause":"`setupSinon` was not imported or called in your `tests/test-helper.js`.","error":"ReferenceError: setupSinon is not defined"},{"fix":"Install `sinon` as a development dependency: `npm install --save-dev sinon` or `yarn add -D sinon`.","cause":"The `sinon` package is missing from your `node_modules`.","error":"Error: Cannot find module 'sinon'"},{"fix":"When stubbing an `@action`, use `sinon.stub(service, 'actionName').get(() => /* stub implementation */);`","cause":"Attempting to stub an `@action` decorated method without using the `.get()` syntax.","error":"TypeError: 'get' is not a function or its return value is not an object"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}