Skip to content

Commit 38c1ee9

Browse files
Merge pull request #1105 from cypress-io/issue-1077-mocha-overspecified-error
add error message for mocha overspecified error
2 parents 4f6edc2 + 56dbe84 commit 38c1ee9

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

source/guides/references/error-messages.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ While this works in practice, it's often indicative of an anti-pattern. You almo
345345

346346
`cy` commands themselves are already promise like, and you can likely avoid the use of the separate Promise.
347347

348+
## {% fa fa-exclamation-triangle red %} Cypress detected that you returned a promise in a test, but also invoked a done callback.
349+
350+
The version of mocha was upgraded with Cypress 4.0. Mocha 3+ no longer allows returning a promise and invoking a done callback. Read more about it in the {% url "4.0 migration guide" migration-guide#Make-changes-related-to-Mocha-upgrade %}.
351+
348352
## {% fa fa-exclamation-triangle red %} Passing `cy.route({stub: false})` or `cy.server({stub: false})` is now deprecated.
349353

350354
You can safely remove: `{stub: false}`.

source/guides/references/migration-guide.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,85 @@ module.exports = (on) => {
147147
}
148148
```
149149

150+
## Make changes related to mocha upgrade
151+
152+
Mocha has been upgraded to Mocha 5.
153+
154+
Starting with [mocha 3.0.0](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md#300--2016-07-31), invoking a `done` callback *and* returning a promise in a test results in an error.
155+
156+
This error originates from mocha and is discussed at length [here](https://github.com/mochajs/mocha/pull/1320) and [here](https://github.com/mochajs/mocha/issues/2407).
157+
158+
The reason is that using two different ways to signal that a test is finished is usually a mistake, and there is always a way to only use one. There is a [proposal to handle this situation without erroring](https://github.com/mochajs/mocha/issues/2509) that may be released in a future version of mocha.
159+
160+
In the meantime, you can fix the error by choosing one way or the other to signal the end of your test's execution.
161+
162+
Given the following test:
163+
164+
```javascript
165+
it('uses invokes done and returns promise', function (done) {
166+
return codeUnderTest.doSomethingThatReturnsPromise().then((result) => {
167+
// assertions here
168+
done()
169+
})
170+
})
171+
```
172+
173+
You don't need the `done` callback. Just return the promise instead:
174+
175+
```javascript
176+
it('uses invokes done and returns promise', function () {
177+
return codeUnderTest.doSomethingThatReturnsPromise().then((result) => {
178+
// assertions here
179+
})
180+
})
181+
```
182+
183+
Sometimes it might make more sense to use the `done` callback and not return a promise:
184+
185+
```javascript
186+
it('uses invokes done and returns promise', function (done) {
187+
eventEmitter.on('change', () => {
188+
// assertions
189+
done()
190+
})
191+
192+
return eventEmitter.doSomethingThatEmitsChange()
193+
})
194+
```
195+
196+
In this case, you don't need to return the promise:
197+
198+
```javascript
199+
it('uses invokes done and returns promise', function (done) {
200+
eventEmitter.on('change', () => {
201+
// assertions
202+
done()
203+
})
204+
205+
eventEmitter.doSomethingThatEmitsChange()
206+
})
207+
```
208+
209+
Test functions using `async/await` automatically return a promise, so they need to be refactored to not use a `done` callback.
210+
211+
```javascript
212+
// Will cause overspecified error
213+
it('uses async/await', async function (done) {
214+
const eventEmitter = await getEventEmitter()
215+
eventEmitter.on('change', () => done())
216+
eventEmitter.doSomethingThatEmitsChange()
217+
})
218+
219+
// Update to this
220+
it('uses async/await', async function () {
221+
const eventEmitter = await getEventEmitter()
222+
return new Promise((resolve) => {
223+
eventEmitter.on('change', () => resolve())
224+
eventEmitter.doSomethingThatEmitsChange()
225+
})
226+
})
227+
```
228+
150229
## Make changes related to Chai upgrade
151230

152231
Chai 3 has been upgraded to Chai 4, which includes a number of breaking changes and new features outlined in [Chai's migration guide](https://github.com/chaijs/chai/issues/781). Some changes you might notice include:

0 commit comments

Comments
 (0)