Closed Sporradik closed 2 years ago
@Sporradik I think the issue here is timing. What we can do is use cy.wrap
to wrap the call to obj.method()
so that we can assert after this call finishes, like this:
try {
cy.wrap(obj.method()).then(() => {
expect(spy).to.have.thrown(Error)
})
} catch (e) {
console.error(e)
}
This should work for asserting that method
throws an error when we call it.
@astone123, Does this work for you? If I do this, then the .then
callback does not run because obj.method()
throws an error.
This example I posted is an overly simplified version of what I am trying to do in my real test. In the real test the method I am spying is called within the method I am calling in the test.
Both in my simplified example and in my real test, the assertion does run after the method was called, as you can see by the message in the error screenshot I posted above. It says "The following calls were made..."
@Sporradik The parameter for the expect(...).to.have.thrown(<here>)
can be undefined
, an object, or a string. For your original test above, passing in Error
is asking the assertion to check that it threw that specific object instance, which it is not. Instead, you can pass in the string 'Error'
to assert that it throws an error of type Error
. Below are a few other examples to look at.
describe.only('test throw', function () {
it('should throw', function () {
const obj = {
method: () => {
throw new Error('error')
}
}
const spy = cy.spy(obj, 'method')
try {
obj.method()
} catch (e) {
console.error(e)
}
expect(spy).to.have.thrown('Error')
})
it('should throw anything', function () {
const obj = {
method: () => {
throw new Error('error')
}
}
const spy = cy.spy(obj, 'method')
try {
obj.method()
} catch (e) {
console.error(e)
}
expect(spy).to.have.thrown()
})
it('should throw specific error', function () {
const error = new Error('my error')
const obj = {
method: () => {
throw error
}
}
const spy = cy.spy(obj, 'method')
try {
obj.method()
} catch (e) {
console.error(e)
}
expect(spy).to.have.thrown(error)
})
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
it('should throw', function () {
const obj = {
method: () => {
throw new ValidationError('not valid')
}
}
const spy = cy.spy(obj, 'method')
try {
obj.method()
} catch (e) {
console.error(e)
}
expect(spy).to.have.thrown('ValidationError')
})
})
Thank you so much @warrensplayer, this is exactly what i was looking for!
Current behavior
I have worked a bunch with spies and calledOnce, etc. I tried to use
expect(spy).to.have.thrown
and it does not seem to be working as I would expect based on the documentation. Am I using this correctly? It essentially gives me the same message if I pass in undefined or a string.Desired behavior
I would expect the above code to pass the expect assertion. (However if this is wrong, I would like to understand the proper method)
Test code to reproduce
Cypress Version
10.7.0
Node version
12.22.12
Operating System
macOs 12.2.1
Debug Logs