docs/concepts/stubs/index.md
::: warning Consider Using Fakes Instead
Fakes are the recommended alternative to stubs for most use cases. They provide simpler, immutable behavior with the same spy API. Consider using sinon.fake.returns(), sinon.fake.throws(), etc. instead of stubs for new code. Stubs remain useful for advanced scenarios like call-specific behavior (onCall()) and property stubbing.
:::
Test stubs are functions, like spies, with pre-programmed behavior.
They support the full test spy API in addition to methods which can be used to alter the stub's behavior.
Like spies, stubs can be either standalone, or wrap existing functions. When wrapping an existing function with a stub, the original function is not called.
Use a stub when you want to:
Control a method's behavior from a test, to force the code down a specific path. Examples include forcing a method to throw an error in order to test error handling.
import * as sinon from "sinon";
const o = {
greet: function (name) {
console.log(`Hello ${name}`);
}
};
// stub out the greet method and make it throw the error we need for our test
const stub = sinon.stub(o, "greet").throws(new Error("I lost my pie :("));
try {
o.greet("Eleanor Rigby");
} catch (error) {
console.log(error);
// => I lost my pie :(
}
When you want to prevent a specific method from being called directly (possibly because it triggers undesired behavior, such as readFile or similar).
import * as sinon from "sinon";
import * as fs from "fs";
// stub out the readFile method
sinon.stub(fs, "readFile").callsFake(function () {
// and make it return the value we want for our test
return Promise.resolve("Apple pie");
});
const fileContent = await fs.readFile("somefile");
console.log(fileContent);
// => Apple pie
Calling behavior defining methods like returns or throws multiple times overrides the behavior of the stub. You can use the onCall method to make a stub respond differently on
consecutive calls.