docs/concepts/spies/index.md
::: warning Consider Using Fakes Instead
Fakes are the recommended alternative to spies. They provide the same functionality with a simpler, more consistent API. Consider using sinon.fake() instead of sinon.spy() for new code.
:::
A test spy is a function that records arguments, return value, the value of
this and exception thrown (if any) for all its calls. There are two types of spies:
Some are anonymous functions, while others wrap methods that already exist in
the system under test.
When the behavior of the spied-on function is not under test, you can use an anonymous function spy. The spy won't do anything except record information about its calls. A common use case for this type of spy is testing how a function handles a callback, as in the following simplified example:
<<< @/.vitepress/tests/docs/spies/_index-1.test.js
sinon.spy(object)
Spies all the object's methods.
Note that it's usually better practice to spy individual methods, particularly on objects that you don't understand or control all the methods for (e.g. library dependencies).
Spying individual methods tests intent more precisely and is less susceptible to unexpected behavior as the object's code evolves.
The following is a slightly contrived example:
<<< @/.vitepress/tests/docs/spies/_index-2.test.js
sinon.spy(object, "method") creates a spy that wraps the existing function
object.method. The spy will behave exactly like the original method
(including when used as a constructor), but you will have access to data about
all calls. The following is a slightly contrived example:
<<< @/.vitepress/tests/docs/spies/_index-3.test.js
sinon.spy(object, "property", ["get", "set"]) creates spies that wrap the
getters and setters for object.property. The spies will behave exactly like
the original getters and setters, but you will have access to data about all
calls. Example:
<<< @/.vitepress/tests/docs/spies/_index-4.test.js
sinon.spy() Method SignaturesCheck out the full list of methods and properties.
Spies provide a rich interface to inspect their usage. The above examples showed
the calledOnce boolean property as well as the getCall method and the
returned object's args property. There are three ways of inspecting call data.
The preferred approach is to use the spy's calledWith method (and friends)
because it keeps your test from being too specific about which call did what and
so on. It will return true if the spy was ever called with the provided
arguments.
If you want to be specific, you can directly check the first argument of the first call. There are two ways of achieving this:
The first example uses the two-dimensional args array directly on the spy,
while the second example fetches the first call object and then accesses its
args array. Which one to use is a matter of preference, but the recommended
approach is going with spy.calledWith(arg1, arg2, ...) unless there's a need
to make the tests highly specific.