Frequently Asked Questions
Frequently Asked Questions
Property Descriptor Errors
“Descriptor for property X is non-configurable and non-writable”
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.
Common Causes
-
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.
Solutions
-
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
proxyquireortestdouble.jsfor 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.
For TypeScript Users
When using TypeScript with SWC or similar transpilers, see our TypeScript with SWC guide for specific solutions.
