Skip to content

Commit

Permalink
fix(vitest): return detailed error when using toHaveReturnedWith (#2163)
Browse files Browse the repository at this point in the history
  • Loading branch information
azaleta committed Oct 19, 2022
1 parent 17ba76b commit c00bc88
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 5 deletions.
36 changes: 31 additions & 5 deletions packages/vitest/src/integrations/chai/jest-expect.ts
Expand Up @@ -394,6 +394,20 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
msg += c.gray(`\n\nNumber of calls: ${c.bold(spy.mock.calls.length)}\n`)
return msg
}
const formatReturns = (spy: EnhancedSpy, msg: string, actualReturn?: any) => {
msg += c.gray(`\n\nReceived: \n${spy.mock.results.map((callReturn, i) => {
let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:\n\n`)
if (actualReturn)
methodCall += unifiedDiff(stringify(callReturn.value), stringify(actualReturn), { showLegend: false })
else
methodCall += stringify(callReturn).split('\n').map(line => ` ${line}`).join('\n')
methodCall += '\n'
return methodCall
}).join('\n')}`)
msg += c.gray(`\n\nNumber of calls: ${c.bold(spy.mock.calls.length)}\n`)
return msg
}
def(['toHaveBeenCalledTimes', 'toBeCalledTimes'], function (number: number) {
const spy = getSpy(this)
const spyName = spy.getMockName()
Expand Down Expand Up @@ -589,12 +603,24 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
const spy = getSpy(this)
const spyName = spy.getMockName()
const pass = spy.mock.results.some(({ type, value: result }) => type === 'return' && jestEquals(value, result))
this.assert(
pass,
`expected "${spyName}" to be successfully called with #{exp}`,
`expected "${spyName}" to not be successfully called with #{exp}`,
value,
const isNot = utils.flag(this, 'negate') as boolean

let msg = utils.getMessage(
this,
[
pass,
`expected "${spyName}" to return with: #{exp} at least once`,
`expected "${spyName}" to not return with: #{exp}`,
value,
],
)

if ((pass && isNot) || (!pass && !isNot)) {
msg = formatReturns(spy, msg, value)
const err = new Error(msg)
err.name = 'AssertionError'
throw err
}
})
def(['toHaveLastReturnedWith', 'lastReturnedWith'], function (value: any) {
const spy = getSpy(this)
Expand Down
79 changes: 79 additions & 0 deletions test/core/test/__snapshots__/mocked.test.ts.snap
@@ -0,0 +1,79 @@
// Vitest Snapshot v1

exports[`mocked function which fails on toReturnWith > just one call 1`] = `
"expected \\"spy\\" to return with: 2 at least once
Received:
 1st spy call return:
 2
1

Number of calls: 1
"
`;

exports[`mocked function which fails on toReturnWith > multi calls 1`] = `
"expected \\"spy\\" to return with: 2 at least once
Received:
 1st spy call return:
 2
1
 2nd spy call return:
 2
1
 3rd spy call return:
 2
1

Number of calls: 3
"
`;

exports[`mocked function which fails on toReturnWith > oject type 1`] = `
"expected \\"spy\\" to return with: { a: '4' } at least once
Received:
 1st spy call return:
 Object {
- \\"a\\": \\"4\\",
+ \\"a\\": \\"1\\",
}
 2nd spy call return:
 Object {
- \\"a\\": \\"4\\",
+ \\"a\\": \\"1\\",
}
 3rd spy call return:
 Object {
- \\"a\\": \\"4\\",
+ \\"a\\": \\"1\\",
}

Number of calls: 3
"
`;
exports[`mocked function which fails on toReturnWith > zero call 1`] = `
"expected \\"spy\\" to return with: 2 at least once
Received:

Number of calls: 0
"
`;
29 changes: 29 additions & 0 deletions test/core/test/mocked.test.ts
Expand Up @@ -134,6 +134,35 @@ test('async functions should be mocked', () => {
expect(asyncFunc()).resolves.toBe('foo')
})

describe('mocked function which fails on toReturnWith', () => {
test('zero call', () => {
const mock = vi.fn(() => 1)
expect(() => expect(mock).toReturnWith(2)).toThrowErrorMatchingSnapshot()
})

test('just one call', () => {
const mock = vi.fn(() => 1)
mock()
expect(() => expect(mock).toReturnWith(2)).toThrowErrorMatchingSnapshot()
})

test('multi calls', () => {
const mock = vi.fn(() => 1)
mock()
mock()
mock()
expect(() => expect(mock).toReturnWith(2)).toThrowErrorMatchingSnapshot()
})

test('oject type', () => {
const mock = vi.fn(() => { return { a: '1' } })
mock()
mock()
mock()
expect(() => expect(mock).toReturnWith({ a: '4' })).toThrowErrorMatchingSnapshot()
})
})

// This is here because mocking streams previously caused some problems (#1671).
test('streams', () => {
expect(exportedStream).toBeDefined()
Expand Down

0 comments on commit c00bc88

Please sign in to comment.