I've run into this problem, and have since found the issue, but as documentation for other users I'm posting what I've found here. Also note, seasoned JS developers probably already understand what my error was here, this is just for developers new to JS like me.
I've got a saga that goes something like this:
function* patchCart({ payload: { data, sections } }) {
const current = yield select(cartSelectors.getCartModel);
const oldAttributes = pick(current, keys(data));
try {
yield call(patchCartTry, data, sections);
} catch (error) {
yield call(patchCartError, error, oldAttributes);
}
}
In my test I was trying to test the catch block of the saga. Part of my test code looked like:
let current = iterator.next().value;
expect(current).toEqual(select(cartSelectors.getCartModel));
current = iterator.throw(error).value;
expect(current).toEqual(call(utilities.patchCartCatch, error, oldAttributes));
The result of running the test gave an output similar to:
Error
[object Object] thrown
Looking all over the internet I could not find an answer, every person I ran across that had this issue, their error was caused by not calling .next()
on their iterator - which I was already doing.
Even logging inside of the saga in the catch block wasn't firing, so I knew the test was never actually getting inside there.
Stay tuned for the answer and subsequent explanation.
The problem was, while I was calling .next()
I wasn't calling it enough times.
All the resources I had read stated you needed to call .next()
to get into the generator function, but none of them mentioned that the reason you needed to call it before calling .throw(error)
is that you need to iterate your function into the try
block. The test is behaving exactly as it should, you threw an exception outside of a try/catch
and thus the test threw an error.
So to fix my test I had to change it to:
let current = iterator.next().value;
expect(current).toEqual(select(cartSelectors.getCartModel));
current = iterator.next().value;
expect(current).toEqual(call(utilities.patchCartTry, data, sections));
current = iterator.throw(error).value;
expect(current).toEqual(call(utilities.patchCartCatch, error, oldAttributes));
Thus assuring that I was inside the try
block before throwing the exception that would take me into my catch
block.
And because credit for this revelation - to me it was a revelation - is due to someone else, here is the link to the comment that helped me solve this. github issue comment