-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
Clear and concise description of the problem
Custom errors with additional attributes are hard to test using toThrowErrorMatchingInlineSnapshot
Example:
class ErrorWithDetails extends Error {
readonly details: unknown
constructor(message: string, options: ErrorOptions & { details: unknown }) {
super(message, options)
this.details = options.details
}
}
describe('ErrorWithDetails', () => {
it('should throw an error with details', () => {
expect(() => {
throw new ErrorWithDetails('Example', { details: 'interesting detail' })
}).toThrowErrorMatchingInlineSnapshot('"Example"') // 'interesting detail' is lost
})
})Suggested solution
Add an addErrorSerializer which works like addSnapshotSerializer, but for errors.
Example:
expect.addErrorSerializer({
serialize(val, config, indentation, depth, refs, printer) {
const error = val as ErrorWithDetails
return `${error.message}: ${printer(error.details, config, indentation, depth, refs)}`
},
test(val) {
return val && val instanceof ErrorWithDetails
},
})which could then result in:
class ErrorWithDetails extends Error {
readonly details: unknown
constructor(message: string, options: ErrorOptions & { details: unknown }) {
super(message, options)
this.details = options.details
}
}
describe('ErrorWithDetails', () => {
it('should throw an error with details', () => {
expect(() => {
throw new ErrorWithDetails('Example', { details: 'interesting detail' })
}).toThrowErrorMatchingInlineSnapshot('"Example: interesting detail"')
})
})Alternative
We can work around that issue, but it is cumbersome:
class ErrorWithDetails extends Error {
readonly details: unknown
constructor(message: string, options: ErrorOptions & { details: unknown }) {
super(message, options)
this.details = options.details
}
}
describe('ErrorWithDetails', () => {
it('should throw an error with details', () => {
expect(
catchAndSerializeError(() => {
throw new ErrorWithDetails('Example', { details: 'interesting detail' })
})
).toMatchInlineSnapshot('"Example \\"interesting detail\\""')
})
})
function catchAndSerializeError(fn: () => any) {
try {
fn()
throw new Error('Expected an error')
} catch (error) {
if (error instanceof ErrorWithDetails) {
return `${error.message} ${JSON.stringify(error.details)}`
}
throw new Error('Expected an ErrorWithDetails')
}
}Additional context
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels