docs/faq.md
If you encounter an error like this:
TypeError: Descriptor for property toBeMocked is non-configurable and non-writable
This error occurs when Sinon tries to stub or spy on a property that has been defined as immutable by JavaScript's property descriptor system. This is not a bug in Sinon, but rather a limitation imposed by the JavaScript engine itself.
ES Module transpilation: When ES modules are transpiled to CommonJS (e.g., by TypeScript, Babel, or SWC), the exported properties often become non-configurable and non-writable.
Object.freeze() or Object.seal(): Objects that have been frozen or sealed have immutable properties.
Native browser/Node.js APIs: Some built-in objects and their properties are inherently immutable.
Third-party libraries: Some libraries define their exports with non-configurable descriptors.
Use dependency injection: Instead of stubbing the import directly, pass the dependency as a parameter:
// Instead of this:
import { toBeMocked } from "./module";
sinon.stub(module, "toBeMocked"); // This might fail
// Do this:
function myFunction(dependency = toBeMocked) {
return dependency();
}
// In tests:
const stub = sinon.stub();
myFunction(stub);
Stub at the module level: For ES modules, consider using a tool like proxyquire or testdouble.js for module-level mocking.
Use dynamic imports: Dynamic imports can sometimes work around transpilation issues:
// In your test
const module = await import("./module");
sinon.stub(module, "toBeMocked");
Restructure your code: Consider whether the code under test can be refactored to be more testable.
When using TypeScript with SWC or similar transpilers, see our [TypeScript with SWC guide]({% link _howto/typescript-swc.md %}) for specific solutions.