@vitest-agent/mcp 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +1 -2
  2. package/index.d.ts +2 -2
  3. package/index.js +1 -1
  4. package/package.json +1 -1
  5. package/server.js +2 -4
  6. package/patterns/_meta.json +0 -67
  7. package/patterns/authoring-a-custom-vitest-agent-reporter.md +0 -82
  8. package/patterns/known-issues-and-caveats.md +0 -52
  9. package/patterns/operating-vitest-agent-as-an-agent.md +0 -62
  10. package/patterns/running-tests-via-mcp.md +0 -103
  11. package/patterns/silencing-leaking-output-in-tests.md +0 -91
  12. package/patterns/testing-effect-schema-definitions.md +0 -71
  13. package/patterns/testing-effect-services-with-mock-layers.md +0 -63
  14. package/resources/index.js +0 -166
  15. package/resources/indexes.js +0 -77
  16. package/resources/manifest-schema.js +0 -46
  17. package/resources/paths.js +0 -20
  18. package/resources/patterns.js +0 -22
  19. package/resources/upstream-docs.js +0 -22
  20. package/vendor/vitest-docs/ATTRIBUTION.md +0 -5
  21. package/vendor/vitest-docs/api/advanced/artifacts.md +0 -189
  22. package/vendor/vitest-docs/api/advanced/metadata.md +0 -68
  23. package/vendor/vitest-docs/api/advanced/plugin.md +0 -168
  24. package/vendor/vitest-docs/api/advanced/reporters.md +0 -342
  25. package/vendor/vitest-docs/api/advanced/runner.md +0 -334
  26. package/vendor/vitest-docs/api/advanced/test-case.md +0 -302
  27. package/vendor/vitest-docs/api/advanced/test-collection.md +0 -89
  28. package/vendor/vitest-docs/api/advanced/test-module.md +0 -140
  29. package/vendor/vitest-docs/api/advanced/test-project.md +0 -321
  30. package/vendor/vitest-docs/api/advanced/test-specification.md +0 -96
  31. package/vendor/vitest-docs/api/advanced/test-suite.md +0 -230
  32. package/vendor/vitest-docs/api/advanced/vitest.md +0 -684
  33. package/vendor/vitest-docs/api/assert-type.md +0 -22
  34. package/vendor/vitest-docs/api/assert.md +0 -1960
  35. package/vendor/vitest-docs/api/browser/assertions.md +0 -1277
  36. package/vendor/vitest-docs/api/browser/commands.md +0 -154
  37. package/vendor/vitest-docs/api/browser/context.md +0 -338
  38. package/vendor/vitest-docs/api/browser/interactivity.md +0 -681
  39. package/vendor/vitest-docs/api/browser/locators.md +0 -1171
  40. package/vendor/vitest-docs/api/browser/react.md +0 -346
  41. package/vendor/vitest-docs/api/browser/svelte.md +0 -292
  42. package/vendor/vitest-docs/api/browser/vue.md +0 -222
  43. package/vendor/vitest-docs/api/describe.md +0 -374
  44. package/vendor/vitest-docs/api/expect-typeof.md +0 -571
  45. package/vendor/vitest-docs/api/expect.md +0 -2304
  46. package/vendor/vitest-docs/api/hooks.md +0 -463
  47. package/vendor/vitest-docs/api/mock.md +0 -701
  48. package/vendor/vitest-docs/api/test.md +0 -926
  49. package/vendor/vitest-docs/api/vi.md +0 -1372
  50. package/vendor/vitest-docs/config/alias.md +0 -13
  51. package/vendor/vitest-docs/config/allowonly.md +0 -32
  52. package/vendor/vitest-docs/config/api.md +0 -27
  53. package/vendor/vitest-docs/config/attachmentsdir.md +0 -6
  54. package/vendor/vitest-docs/config/bail.md +0 -9
  55. package/vendor/vitest-docs/config/benchmark.md +0 -65
  56. package/vendor/vitest-docs/config/browser/api.md +0 -23
  57. package/vendor/vitest-docs/config/browser/commands.md +0 -6
  58. package/vendor/vitest-docs/config/browser/connecttimeout.md +0 -10
  59. package/vendor/vitest-docs/config/browser/detailspanelposition.md +0 -38
  60. package/vendor/vitest-docs/config/browser/enabled.md +0 -40
  61. package/vendor/vitest-docs/config/browser/expect.md +0 -250
  62. package/vendor/vitest-docs/config/browser/headless.md +0 -7
  63. package/vendor/vitest-docs/config/browser/instances.md +0 -47
  64. package/vendor/vitest-docs/config/browser/isolate.md +0 -11
  65. package/vendor/vitest-docs/config/browser/locators.md +0 -24
  66. package/vendor/vitest-docs/config/browser/orchestratorscripts.md +0 -39
  67. package/vendor/vitest-docs/config/browser/playwright.md +0 -214
  68. package/vendor/vitest-docs/config/browser/preview.md +0 -32
  69. package/vendor/vitest-docs/config/browser/provider.md +0 -79
  70. package/vendor/vitest-docs/config/browser/screenshotdirectory.md +0 -6
  71. package/vendor/vitest-docs/config/browser/screenshotfailures.md +0 -6
  72. package/vendor/vitest-docs/config/browser/testerhtmlpath.md +0 -5
  73. package/vendor/vitest-docs/config/browser/trace.md +0 -43
  74. package/vendor/vitest-docs/config/browser/trackunhandlederrors.md +0 -10
  75. package/vendor/vitest-docs/config/browser/ui.md +0 -7
  76. package/vendor/vitest-docs/config/browser/viewport.md +0 -6
  77. package/vendor/vitest-docs/config/browser/webdriverio.md +0 -64
  78. package/vendor/vitest-docs/config/cache.md +0 -26
  79. package/vendor/vitest-docs/config/chaiconfig.md +0 -29
  80. package/vendor/vitest-docs/config/clearmocks.md +0 -22
  81. package/vendor/vitest-docs/config/coverage.md +0 -455
  82. package/vendor/vitest-docs/config/css.md +0 -47
  83. package/vendor/vitest-docs/config/dangerouslyignoreunhandlederrors.md +0 -23
  84. package/vendor/vitest-docs/config/deps.md +0 -127
  85. package/vendor/vitest-docs/config/detectasyncleaks.md +0 -39
  86. package/vendor/vitest-docs/config/diff.md +0 -96
  87. package/vendor/vitest-docs/config/dir.md +0 -7
  88. package/vendor/vitest-docs/config/disableconsoleintercept.md +0 -15
  89. package/vendor/vitest-docs/config/env.md +0 -5
  90. package/vendor/vitest-docs/config/environment.md +0 -96
  91. package/vendor/vitest-docs/config/environmentoptions.md +0 -30
  92. package/vendor/vitest-docs/config/exclude.md +0 -49
  93. package/vendor/vitest-docs/config/execargv.md +0 -10
  94. package/vendor/vitest-docs/config/expandsnapshotdiff.md +0 -7
  95. package/vendor/vitest-docs/config/expect.md +0 -38
  96. package/vendor/vitest-docs/config/experimental.md +0 -510
  97. package/vendor/vitest-docs/config/faketimers.md +0 -51
  98. package/vendor/vitest-docs/config/fileparallelism.md +0 -11
  99. package/vendor/vitest-docs/config/forcereruntriggers.md +0 -19
  100. package/vendor/vitest-docs/config/globals.md +0 -42
  101. package/vendor/vitest-docs/config/globalsetup.md +0 -72
  102. package/vendor/vitest-docs/config/hideskippedtests.md +0 -7
  103. package/vendor/vitest-docs/config/hooktimeout.md +0 -7
  104. package/vendor/vitest-docs/config/include-source.md +0 -115
  105. package/vendor/vitest-docs/config/include.md +0 -71
  106. package/vendor/vitest-docs/config/includetasklocation.md +0 -17
  107. package/vendor/vitest-docs/config/index.md +0 -85
  108. package/vendor/vitest-docs/config/isolate.md +0 -13
  109. package/vendor/vitest-docs/config/logheapusage.md +0 -7
  110. package/vendor/vitest-docs/config/maxconcurrency.md +0 -9
  111. package/vendor/vitest-docs/config/maxworkers.md +0 -49
  112. package/vendor/vitest-docs/config/mockreset.md +0 -22
  113. package/vendor/vitest-docs/config/mode.md +0 -7
  114. package/vendor/vitest-docs/config/name.md +0 -111
  115. package/vendor/vitest-docs/config/onconsolelog.md +0 -25
  116. package/vendor/vitest-docs/config/onstacktrace.md +0 -32
  117. package/vendor/vitest-docs/config/onunhandlederror.md +0 -35
  118. package/vendor/vitest-docs/config/open.md +0 -7
  119. package/vendor/vitest-docs/config/outputfile.md +0 -7
  120. package/vendor/vitest-docs/config/passwithnotests.md +0 -7
  121. package/vendor/vitest-docs/config/pool.md +0 -45
  122. package/vendor/vitest-docs/config/printconsoletrace.md +0 -6
  123. package/vendor/vitest-docs/config/projects.md +0 -6
  124. package/vendor/vitest-docs/config/provide.md +0 -45
  125. package/vendor/vitest-docs/config/reporters.md +0 -69
  126. package/vendor/vitest-docs/config/resolvesnapshotpath.md +0 -36
  127. package/vendor/vitest-docs/config/restoremocks.md +0 -22
  128. package/vendor/vitest-docs/config/retry.md +0 -140
  129. package/vendor/vitest-docs/config/root.md +0 -6
  130. package/vendor/vitest-docs/config/runner.md +0 -6
  131. package/vendor/vitest-docs/config/sequence.md +0 -158
  132. package/vendor/vitest-docs/config/server.md +0 -68
  133. package/vendor/vitest-docs/config/setupfiles.md +0 -40
  134. package/vendor/vitest-docs/config/silent.md +0 -9
  135. package/vendor/vitest-docs/config/slowtestthreshold.md +0 -7
  136. package/vendor/vitest-docs/config/snapshotenvironment.md +0 -27
  137. package/vendor/vitest-docs/config/snapshotformat.md +0 -28
  138. package/vendor/vitest-docs/config/snapshotserializers.md +0 -6
  139. package/vendor/vitest-docs/config/stricttags.md +0 -30
  140. package/vendor/vitest-docs/config/tags.md +0 -141
  141. package/vendor/vitest-docs/config/teardowntimeout.md +0 -7
  142. package/vendor/vitest-docs/config/testnamepattern.md +0 -21
  143. package/vendor/vitest-docs/config/testtimeout.md +0 -7
  144. package/vendor/vitest-docs/config/typecheck.md +0 -77
  145. package/vendor/vitest-docs/config/ui.md +0 -15
  146. package/vendor/vitest-docs/config/unstubenvs.md +0 -20
  147. package/vendor/vitest-docs/config/unstubglobals.md +0 -20
  148. package/vendor/vitest-docs/config/update.md +0 -16
  149. package/vendor/vitest-docs/config/vmmemorylimit.md +0 -30
  150. package/vendor/vitest-docs/config/watch.md +0 -11
  151. package/vendor/vitest-docs/config/watchtriggerpatterns.md +0 -29
  152. package/vendor/vitest-docs/guide/advanced/index.md +0 -147
  153. package/vendor/vitest-docs/guide/advanced/pool.md +0 -148
  154. package/vendor/vitest-docs/guide/advanced/reporters.md +0 -93
  155. package/vendor/vitest-docs/guide/advanced/tests.md +0 -125
  156. package/vendor/vitest-docs/guide/browser/aria-snapshots.md +0 -470
  157. package/vendor/vitest-docs/guide/browser/component-testing.md +0 -571
  158. package/vendor/vitest-docs/guide/browser/index.md +0 -630
  159. package/vendor/vitest-docs/guide/browser/multiple-setups.md +0 -121
  160. package/vendor/vitest-docs/guide/browser/trace-view.md +0 -126
  161. package/vendor/vitest-docs/guide/browser/visual-regression-testing.md +0 -734
  162. package/vendor/vitest-docs/guide/cli-generated.md +0 -972
  163. package/vendor/vitest-docs/guide/cli.md +0 -234
  164. package/vendor/vitest-docs/guide/common-errors.md +0 -163
  165. package/vendor/vitest-docs/guide/coverage.md +0 -515
  166. package/vendor/vitest-docs/guide/debugging.md +0 -127
  167. package/vendor/vitest-docs/guide/environment.md +0 -101
  168. package/vendor/vitest-docs/guide/extending-matchers.md +0 -160
  169. package/vendor/vitest-docs/guide/features.md +0 -310
  170. package/vendor/vitest-docs/guide/filtering.md +0 -175
  171. package/vendor/vitest-docs/guide/ide.md +0 -43
  172. package/vendor/vitest-docs/guide/improving-performance.md +0 -245
  173. package/vendor/vitest-docs/guide/in-source.md +0 -159
  174. package/vendor/vitest-docs/guide/index.md +0 -128
  175. package/vendor/vitest-docs/guide/learn/async.md +0 -147
  176. package/vendor/vitest-docs/guide/learn/debugging-tests.md +0 -210
  177. package/vendor/vitest-docs/guide/learn/matchers.md +0 -277
  178. package/vendor/vitest-docs/guide/learn/mock-functions.md +0 -277
  179. package/vendor/vitest-docs/guide/learn/setup-teardown.md +0 -240
  180. package/vendor/vitest-docs/guide/learn/snapshots.md +0 -166
  181. package/vendor/vitest-docs/guide/learn/testing-in-practice.md +0 -430
  182. package/vendor/vitest-docs/guide/learn/writing-tests-with-ai.md +0 -127
  183. package/vendor/vitest-docs/guide/learn/writing-tests.md +0 -231
  184. package/vendor/vitest-docs/guide/lifecycle.md +0 -379
  185. package/vendor/vitest-docs/guide/migration.md +0 -863
  186. package/vendor/vitest-docs/guide/mocking/classes.md +0 -158
  187. package/vendor/vitest-docs/guide/mocking/dates.md +0 -52
  188. package/vendor/vitest-docs/guide/mocking/file-system.md +0 -74
  189. package/vendor/vitest-docs/guide/mocking/functions.md +0 -61
  190. package/vendor/vitest-docs/guide/mocking/globals.md +0 -20
  191. package/vendor/vitest-docs/guide/mocking/modules.md +0 -414
  192. package/vendor/vitest-docs/guide/mocking/requests.md +0 -114
  193. package/vendor/vitest-docs/guide/mocking/timers.md +0 -48
  194. package/vendor/vitest-docs/guide/mocking.md +0 -239
  195. package/vendor/vitest-docs/guide/open-telemetry.md +0 -156
  196. package/vendor/vitest-docs/guide/parallelism.md +0 -82
  197. package/vendor/vitest-docs/guide/profiling-test-performance.md +0 -243
  198. package/vendor/vitest-docs/guide/projects.md +0 -291
  199. package/vendor/vitest-docs/guide/recipes.md +0 -59
  200. package/vendor/vitest-docs/guide/reporters.md +0 -723
  201. package/vendor/vitest-docs/guide/snapshot.md +0 -620
  202. package/vendor/vitest-docs/guide/test-annotations.md +0 -103
  203. package/vendor/vitest-docs/guide/test-context.md +0 -902
  204. package/vendor/vitest-docs/guide/test-tags.md +0 -314
  205. package/vendor/vitest-docs/guide/testing-types.md +0 -149
  206. package/vendor/vitest-docs/guide/ui.md +0 -160
  207. package/vendor/vitest-docs/guide/using-plugins.md +0 -5
  208. package/vendor/vitest-docs/manifest.json +0 -1691
@@ -1,414 +0,0 @@
1
- # Mocking Modules
2
-
3
- ## Defining a Module
4
-
5
- Before mocking a "module", we should define what it is. In Vitest context, the "module" is a file that exports something. Using [plugins](https://vite.dev/guide/api-plugin.html), any file can be turned into a JavaScript module. The "module object" is a namespace object that holds dynamic references to exported identifiers. Simply put, it's an object with exported methods and properties. In this example, `example.js` is a module that exports `answer` and `variable`:
6
-
7
- ```js [example.js]
8
- export function answer() {
9
- // ...
10
- return 42
11
- }
12
-
13
- export const variable = 'example'
14
- ```
15
-
16
- The `exampleObject` here is a module object:
17
-
18
- ```js [example.test.js]
19
- import * as exampleObject from './example.js'
20
- ```
21
-
22
- The `exampleObject` will always exist even if you imported the example using named imports:
23
-
24
- ```js [example.test.js]
25
- import { answer, variable } from './example.js'
26
- ```
27
-
28
- You can only reference `exampleObject` outside the example module itself. For example, in a test.
29
-
30
- ## Mocking a Module
31
-
32
- For the purpose of this guide, let's introduce some definitions.
33
-
34
- - **Mocked module** is a module that was completely replaced with another one.
35
- - **Spied module** is a mocked module, but its exported methods keep the original implementation. They can also be tracked.
36
- - **Mocked export** is a module export, which invocations can be tracked.
37
- - **Spied export** is a mocked export.
38
-
39
- To mock a module completely, you can use the [`vi.mock` API](/api/vi#vi-mock). You can define a new module dynamically by providing a factory that returns a new module as a second argument:
40
-
41
- ```ts
42
- import { vi } from 'vitest'
43
-
44
- // The ./example.js module will be replaced with
45
- // the result of a factory function, and the
46
- // original ./example.js module will never be called
47
- vi.mock(import('./example.js'), () => {
48
- return {
49
- answer() {
50
- // ...
51
- return 42
52
- },
53
- variable: 'mock',
54
- }
55
- })
56
- ```
57
-
58
- ::: tip
59
- Remember that you can call `vi.mock` in a [setup file](/config/setupfiles) to apply the module mock in every test file automatically.
60
- :::
61
-
62
- ::: tip
63
- Note the usage of dynamic import: `import('./example.ts')`. Vitest will strip it before the code is executed, but it allows TypeScript to properly validate the string and type the `importOriginal` method in your IDE or CLI.
64
- :::
65
-
66
- If your code is trying to access a method that was not returned from this factory, Vitest will throw an error with a helpful message. Note that `answer` is not mocked, i.e. it cannot be tracked. To make it trackable, use `vi.fn()` instead:
67
-
68
- ```ts
69
- import { vi } from 'vitest'
70
-
71
- vi.mock(import('./example.js'), () => {
72
- return {
73
- answer: vi.fn(),
74
- variable: 'mock',
75
- }
76
- })
77
- ```
78
-
79
- The factory method accepts an `importOriginal` function that will execute the original module and return its module object:
80
-
81
- ```ts
82
- import { expect, vi } from 'vitest'
83
- import { answer } from './example.js'
84
-
85
- vi.mock(import('./example.js'), async (importOriginal) => {
86
- const originalModule = await importOriginal()
87
- return {
88
- answer: vi.fn(originalModule.answer),
89
- variable: 'mock',
90
- }
91
- })
92
-
93
- expect(answer()).toBe(42)
94
-
95
- expect(answer).toHaveBeenCalled()
96
- expect(answer).toHaveReturned(42)
97
- ```
98
-
99
- ::: warning
100
- Note that `importOriginal` is asynchronous and needs to be awaited.
101
- :::
102
-
103
- In the above example, we provided the original `answer` to the `vi.fn()` call so it can keep calling it while being tracked at the same time.
104
-
105
- If you require the use of `importOriginal`, consider spying on the export directly via another API: `vi.spyOn`. Instead of replacing the whole module, you can spy only on a single exported method. To do that, you need to import the module as a namespace object:
106
-
107
- ```ts
108
- import { expect, vi } from 'vitest'
109
- import * as exampleObject from './example.js'
110
-
111
- const spy = vi.spyOn(exampleObject, 'answer').mockReturnValue(0)
112
-
113
- expect(exampleObject.answer()).toBe(0)
114
- expect(exampleObject.answer).toHaveBeenCalled()
115
- ```
116
-
117
- ::: danger Browser Mode Support
118
- This will not work in the [Browser Mode](/guide/browser/) because it uses the browser's native ESM support to serve modules. The module namespace object is sealed and can't be reconfigured. To bypass this limitation, Vitest supports `{ spy: true }` option in `vi.mock('./example.js')`. This will automatically spy on every export in the module without replacing them with fake ones.
119
-
120
- ```ts
121
- import { vi } from 'vitest'
122
- import * as exampleObject from './example.js'
123
-
124
- vi.mock('./example.js', { spy: true })
125
-
126
- vi.mocked(exampleObject.answer).mockReturnValue(0)
127
- ```
128
- :::
129
-
130
- ::: warning
131
- You only need to import the module as a namespace object in the file where you are using the `vi.spyOn` utility. If the `answer` is called in another file and is imported there as a named export, Vitest will be able to properly track it as long as the function that called it is called after `vi.spyOn`:
132
-
133
- ```ts [source.js]
134
- import { answer } from './example.js'
135
-
136
- export function question() {
137
- if (answer() === 42) {
138
- return 'Ultimate Question of Life, the Universe, and Everything'
139
- }
140
-
141
- return 'Unknown Question'
142
- }
143
- ```
144
- :::
145
-
146
- Note that `vi.spyOn` will only spy on calls that were done after it spied on the method. So, if the function is executed at the top level during an import or it was called before the spying, `vi.spyOn` will not be able to report on it.
147
-
148
- To automatically mock any module before it is imported, you can call `vi.mock` with a path:
149
-
150
- ```ts
151
- import { vi } from 'vitest'
152
-
153
- vi.mock(import('./example.js'))
154
- ```
155
-
156
- If the file `./__mocks__/example.js` exists, then Vitest will load it instead. Otherwise, Vitest will load the original module and replace everything recursively:
157
-
158
- {#automocking-algorithm}
159
-
160
- - All arrays will be empty
161
- - All primitives will stay untouched
162
- - All getters will return `undefined`
163
- - All methods will return `undefined`
164
- - All objects will be deeply cloned
165
- - All instances of classes and their prototypes will be cloned
166
-
167
- To disable this behavior, you can pass down `spy: true` as the second argument:
168
-
169
- ```ts
170
- import { vi } from 'vitest'
171
-
172
- vi.mock(import('./example.js'), { spy: true })
173
- ```
174
-
175
- Instead of returning `undefined`, all methods will call the original implementation, but you can still keep track of these calls:
176
-
177
- ```ts
178
- import { expect, vi } from 'vitest'
179
- import { answer } from './example.js'
180
-
181
- vi.mock(import('./example.js'), { spy: true })
182
-
183
- // calls the original implementation
184
- expect(answer()).toBe(42)
185
- // vitest can still track the invocations
186
- expect(answer).toHaveBeenCalled()
187
- ```
188
-
189
- One nice thing that mocked modules support is sharing the state between the instance and its prototype. Consider this module:
190
-
191
- ```ts [answer.js]
192
- export class Answer {
193
- constructor(value) {
194
- this._value = value
195
- }
196
-
197
- value() {
198
- return this._value
199
- }
200
- }
201
- ```
202
-
203
- By mocking it, we can keep track of every invocation of `.value()` even without having access to the instance itself:
204
-
205
- ```ts [answer.test.js]
206
- import { expect, test, vi } from 'vitest'
207
- import { Answer } from './answer.js'
208
-
209
- vi.mock(import('./answer.js'), { spy: true })
210
-
211
- test('instance inherits the state', () => {
212
- // these invocations could be private inside another function
213
- // that you don't have access to in your test
214
- const answer1 = new Answer(42)
215
- const answer2 = new Answer(0)
216
-
217
- expect(answer1.value()).toBe(42)
218
- expect(answer1.value).toHaveBeenCalled()
219
- // note that different instances have their own states
220
- expect(answer2.value).not.toHaveBeenCalled()
221
-
222
- expect(answer2.value()).toBe(0)
223
-
224
- // but the prototype state accumulates all calls
225
- expect(Answer.prototype.value).toHaveBeenCalledTimes(2)
226
- expect(Answer.prototype.value).toHaveReturned(42)
227
- expect(Answer.prototype.value).toHaveReturned(0)
228
- })
229
- ```
230
-
231
- This can be very useful to track calls to instances that are never exposed.
232
-
233
- ## Mocking Non-existing Module
234
-
235
- Vitest supports mocking virtual modules. These modules don't exist on the file system, but your code imports them. For example, this can happen when your development environment is different from production. One common example is mocking `vscode` APIs in your unit tests.
236
-
237
- By default, Vitest will fail transforming files if it cannot find the source of the import. To bypass this, you need to specify it in your config. You can either always redirect the import to a file, or just signal Vite to ignore it and use the `vi.mock` factory to define its exports.
238
-
239
- To redirect the import, use [`test.alias`](/config/alias) config option:
240
-
241
- ```ts [vitest.config.ts]
242
- import { defineConfig } from 'vitest/config'
243
- import { resolve } from 'node:path'
244
-
245
- export default defineConfig({
246
- test: {
247
- alias: {
248
- vscode: resolve(import.meta.dirname, './mock/vscode.js'),
249
- },
250
- },
251
- })
252
- ```
253
-
254
- To mark the module as always resolved, return the same string from `resolveId` hook of a plugin:
255
-
256
- ```ts [vitest.config.ts]
257
- import { defineConfig } from 'vitest/config'
258
- import { resolve } from 'node:path'
259
-
260
- export default defineConfig({
261
- plugins: [
262
- {
263
- name: 'virtual-vscode',
264
- resolveId(id) {
265
- if (id === 'vscode') {
266
- return 'vscode'
267
- }
268
- }
269
- }
270
- ]
271
- })
272
- ```
273
-
274
- Now you can use `vi.mock` as usual in your tests:
275
-
276
- ```ts
277
- import { vi } from 'vitest'
278
-
279
- vi.mock(import('vscode'), () => {
280
- return {
281
- window: {
282
- createOutputChannel: vi.fn(),
283
- }
284
- }
285
- })
286
- ```
287
-
288
- ## How it Works
289
-
290
- Vitest implements different module mocking mechanisms depending on the environment. The only feature they share is the plugin transformer. When Vitest sees that a file has `vi.mock` inside, it will transform every static import into a dynamic one and move the `vi.mock` call to the top of the file. This allows Vitest to register the mock before the import happens without breaking the ESM rule of hoisted imports.
291
-
292
- ::: code-group
293
- ```ts [example.js]
294
- import { answer } from './answer.js'
295
-
296
- vi.mock(import('./answer.js'))
297
-
298
- console.log(answer)
299
- ```
300
- ```ts [example.transformed.js]
301
- vi.mock('./answer.js')
302
-
303
- const __vitest_module_0__ = await __handle_mock__(
304
- () => import('./answer.js')
305
- )
306
- // to keep the live binding, we have to access
307
- // the export on the module namespace
308
- console.log(__vitest_module_0__.answer())
309
- ```
310
- :::
311
-
312
- The `__handle_mock__` wrapper just makes sure the mock is resolved before the import is initiated, it doesn't modify the module in any way.
313
-
314
- The module mocking plugins are available in the [`@vitest/mocker` package](https://github.com/vitest-dev/vitest/tree/main/packages/mocker).
315
-
316
- ### JSDOM, happy-dom, Node
317
-
318
- When you run your tests in an emulated environment, Vitest creates a [module runner](https://vite.dev/guide/api-environment-runtimes.html#modulerunner) that can consume Vite code. The module runner is designed in such a way that Vitest can hook into the module evaluation and replace it with the mock, if it was registered. This means that Vitest runs your code in an ESM-like environment, but it doesn't use native ESM mechanism directly. This allows the test runner to bend the rules around ES Modules immutability, allowing users to call `vi.spyOn` on a seemingly ES Module.
319
-
320
- If module runner is [disabled](/config/experimental#experimental-vitemodulerunner) and [node loader](/config/experimental#experimental-nodeloader) is not explicitly disabled, Vitest will [register a loader hook](https://nodejs.org/api/module.html#customization-hooks) that transforms original modules into mocked ones. In this mode users cannot call `vi.spyOn` on an ES Module because Vitest uses a native loader mechanism with all its guard rails. In addition to that, Vitest also has to inject a `mock` query into every mocked module which is visible in the stack trace.
321
-
322
- ### Browser Mode
323
-
324
- Vitest uses native ESM in the Browser Mode. This means that we cannot replace the module so easily. Instead, Vitest intercepts the fetch request (via playwright's `page.route` or a Vite plugin API if using `preview` or `webdriverio`) and serves transformed code, if the module was mocked.
325
-
326
- For example, if the module is automocked, Vitest can parse static exports and create a placeholder module:
327
-
328
- ::: code-group
329
- ```ts [answer.js]
330
- export function answer() {
331
- return 42
332
- }
333
- ```
334
- ```ts [answer.transformed.js]
335
- function answer() {
336
- return 42
337
- }
338
-
339
- const __private_module__ = {
340
- [Symbol.toStringTag]: 'Module',
341
- answer: vi.fn(answer),
342
- }
343
-
344
- export const answer = __private_module__.answer
345
- ```
346
- :::
347
-
348
- The example is simplified for brevity, but the concept is unchanged. We can inject a `__private_module__` variable into the module to hold the mocked values. If the user called `vi.mock` with `spy: true`, we pass down the original value; otherwise, we create a simple `vi.fn()` mock.
349
-
350
- If user defined a custom factory, this makes it harder to inject the code, but not impossible. When the mocked file is served, we first resolve the factory in the browser, then pass down the keys back to the server, and use them to create a placeholder module:
351
-
352
- ```ts
353
- const resolvedFactoryKeys = await resolveBrowserFactory(url)
354
- const mockedModule = `
355
- const __private_module__ = getFactoryReturnValue(${url})
356
- ${resolvedFactoryKeys.map(key => `export const ${key} = __private_module__["${key}"]`).join('\n')}
357
- `
358
- ```
359
-
360
- This module can now be served back to the browser. You can inspect the code in the devtools when you run the tests.
361
-
362
- ## Mocking Modules Pitfalls
363
-
364
- Beware that it is not possible to mock calls to methods that are called inside other methods of the same file. For example, in this code:
365
-
366
- ```ts [foobar.js]
367
- export function foo() {
368
- return 'foo'
369
- }
370
-
371
- export function foobar() {
372
- return `${foo()}bar`
373
- }
374
- ```
375
-
376
- It is not possible to mock the `foo` method from the outside because it is referenced directly. So this code will have no effect on the `foo` call inside `foobar` (but it will affect the `foo` call in other modules):
377
-
378
- ```ts [foobar.test.ts]
379
- import { vi } from 'vitest'
380
- import * as mod from './foobar.js'
381
-
382
- // this will only affect "foo" outside of the original module
383
- vi.spyOn(mod, 'foo')
384
- vi.mock(import('./foobar.js'), async (importOriginal) => {
385
- return {
386
- ...await importOriginal(),
387
- // this will only affect "foo" outside of the original module
388
- foo: () => 'mocked'
389
- }
390
- })
391
- ```
392
-
393
- You can confirm this behavior by providing the implementation to the `foobar` method directly:
394
-
395
- ```ts [foobar.test.js]
396
- import * as mod from './foobar.js'
397
-
398
- vi.spyOn(mod, 'foo')
399
-
400
- // exported foo references mocked method
401
- mod.foobar(mod.foo)
402
- ```
403
-
404
- ```ts [foobar.js]
405
- export function foo() {
406
- return 'foo'
407
- }
408
-
409
- export function foobar(injectedFoo) {
410
- return injectedFoo === foo // false
411
- }
412
- ```
413
-
414
- This is the intended behavior, and we do not plan to implement a workaround. Consider refactoring your code into multiple files or use techniques such as [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection). We believe that making the application testable is not the responsibility of the test runner, but of the application architecture.
@@ -1,114 +0,0 @@
1
- # Mocking Requests
2
-
3
- Because Vitest runs in Node, mocking network requests is tricky; web APIs are not available, so we need something that will mimic network behavior for us. We recommend [Mock Service Worker](https://mswjs.io/) to accomplish this. It allows you to mock `http`, `WebSocket` and `GraphQL` network requests, and is framework agnostic.
4
-
5
- Mock Service Worker (MSW) works by intercepting the requests your tests make, allowing you to use it without changing any of your application code. In-browser, this uses the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). In Node.js, and for Vitest, it uses the [`@mswjs/interceptors`](https://github.com/mswjs/interceptors) library. To learn more about MSW, read their [introduction](https://mswjs.io/docs/)
6
-
7
- ## Configuration
8
-
9
- You can use it like below in your [setup file](/config/setupfiles)
10
-
11
- ::: code-group
12
-
13
- ```js [HTTP Setup]
14
- import { afterAll, afterEach, beforeAll } from 'vitest'
15
- import { setupServer } from 'msw/node'
16
- import { http, HttpResponse } from 'msw'
17
-
18
- const posts = [
19
- {
20
- userId: 1,
21
- id: 1,
22
- title: 'first post title',
23
- body: 'first post body',
24
- },
25
- // ...
26
- ]
27
-
28
- export const restHandlers = [
29
- http.get('https://rest-endpoint.example/path/to/posts', () => {
30
- return HttpResponse.json(posts)
31
- }),
32
- ]
33
-
34
- const server = setupServer(...restHandlers)
35
-
36
- // Start server before all tests
37
- beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
38
-
39
- // Close server after all tests
40
- afterAll(() => server.close())
41
-
42
- // Reset handlers after each test for test isolation
43
- afterEach(() => server.resetHandlers())
44
- ```
45
-
46
- ```js [GraphQL Setup]
47
- import { afterAll, afterEach, beforeAll } from 'vitest'
48
- import { setupServer } from 'msw/node'
49
- import { graphql, HttpResponse } from 'msw'
50
-
51
- const posts = [
52
- {
53
- userId: 1,
54
- id: 1,
55
- title: 'first post title',
56
- body: 'first post body',
57
- },
58
- // ...
59
- ]
60
-
61
- const graphqlHandlers = [
62
- graphql.query('ListPosts', () => {
63
- return HttpResponse.json({
64
- data: { posts },
65
- })
66
- }),
67
- ]
68
-
69
- const server = setupServer(...graphqlHandlers)
70
-
71
- // Start server before all tests
72
- beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
73
-
74
- // Close server after all tests
75
- afterAll(() => server.close())
76
-
77
- // Reset handlers after each test for test isolation
78
- afterEach(() => server.resetHandlers())
79
- ```
80
-
81
- ```js [WebSocket Setup]
82
- import { afterAll, afterEach, beforeAll } from 'vitest'
83
- import { setupServer } from 'msw/node'
84
- import { ws } from 'msw'
85
-
86
- const chat = ws.link('wss://chat.example.com')
87
-
88
- const wsHandlers = [
89
- chat.addEventListener('connection', ({ client }) => {
90
- client.addEventListener('message', (event) => {
91
- console.log('Received message from client:', event.data)
92
- // Echo the received message back to the client
93
- client.send(`Server received: ${event.data}`)
94
- })
95
- }),
96
- ]
97
-
98
- const server = setupServer(...wsHandlers)
99
-
100
- // Start server before all tests
101
- beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
102
-
103
- // Close server after all tests
104
- afterAll(() => server.close())
105
-
106
- // Reset handlers after each test for test isolation
107
- afterEach(() => server.resetHandlers())
108
- ```
109
- :::
110
-
111
- > Configuring the server with `onUnhandledRequest: 'error'` ensures that an error is thrown whenever there is a request that does not have a corresponding request handler.
112
-
113
- ## More
114
- There is much more to MSW. You can access cookies and query parameters, define mock error responses, and much more! To see all you can do with MSW, read [their documentation](https://mswjs.io/docs).
@@ -1,48 +0,0 @@
1
- # Timers
2
-
3
- When we test code that involves timeouts or intervals, instead of having our tests wait it out or timeout, we can speed up our tests by using "fake" timers that mock calls to `setTimeout` and `setInterval`.
4
-
5
- See the [`vi.useFakeTimers` API section](/api/vi#vi-usefaketimers) for a more in depth detailed API description.
6
-
7
- ## Example
8
-
9
- ```js
10
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
11
-
12
- function executeAfterTwoHours(func) {
13
- setTimeout(func, 1000 * 60 * 60 * 2) // 2 hours
14
- }
15
-
16
- function executeEveryMinute(func) {
17
- setInterval(func, 1000 * 60) // 1 minute
18
- }
19
-
20
- const mock = vi.fn(() => console.log('executed'))
21
-
22
- describe('delayed execution', () => {
23
- beforeEach(() => {
24
- vi.useFakeTimers()
25
- })
26
- afterEach(() => {
27
- vi.clearAllMocks()
28
- })
29
- it('should execute the function', () => {
30
- executeAfterTwoHours(mock)
31
- vi.runAllTimers()
32
- expect(mock).toHaveBeenCalledTimes(1)
33
- })
34
- it('should not execute the function', () => {
35
- executeAfterTwoHours(mock)
36
- // advancing by 2ms won't trigger the func
37
- vi.advanceTimersByTime(2)
38
- expect(mock).not.toHaveBeenCalled()
39
- })
40
- it('should execute every minute', () => {
41
- executeEveryMinute(mock)
42
- vi.advanceTimersToNextTimer()
43
- expect(mock).toHaveBeenCalledTimes(1)
44
- vi.advanceTimersToNextTimer()
45
- expect(mock).toHaveBeenCalledTimes(2)
46
- })
47
- })
48
- ```