DEV Community

The best way to test Redux Sagas

Phil Herbert on December 10, 2018

tl;dr: to test a saga, it's way, way better to run it as a whole (using runSaga()) than to do it step-by-step (using gen.next()) In my team, we're...
Collapse
 
royb0y profile image
Roy

This is a great article! Thank you for this!

How would you throw exceptions to test for api call failures?

For example, if you had a try / catch block for,

const profile = yield call(getProfile, action.profileId);

When you test the saga as a whole, how do you force an error?

I tried using to mockImplementation to return a new Error(), but that doesn't go into the catch block.

Collapse
 
noriste profile image
Stefano Magni

I don't know if the APIs are changed, at the moment (Feb, 2020) runSaga returns a Task that has a toPromise() method.
So await runSaga(...).done does not make sense, you need to do

const task = runSaga(...)
const result = await task.toPromise()
expect(result).toStrictEqual({...})
Enter fullscreen mode Exit fullscreen mode

anyway: thank you so much for the article 😊

Collapse
 
worc profile image
worc

we have to check that every yield is not a call to getProfile()

i'm not sure that's entirely true. when i've gone down the path of testing sagas step-by-step, i've thrown gen.next()s into the body of the test without any assertions to get to the step i'm actually trying to test. it's not great and it's pretty brittle if you change your order of operations, but it's not silly either. i don't need to assert that the saga isn't calling a function.

Collapse
 
jonesy profile image
Robert Jones

Phil, this is brilliant- thanks for writing the article. I'm trying to (roughly) define a testing approach for sagas that'll encourage a more maintainable test suite, and I think you've just nailed a decent way of going about it without introducing another dependency!

Collapse
 
matt_chabert profile image
Matthieu Chabert

Agree with you Phil! I've come across this repo where you can set up end to end test for sagas

github.com/jfairbank/redux-saga-te...

Collapse
 
renatonankran profile image
Renato Magalhães

How you got the api calls to be overrided inside the saga?

Collapse
 
brayanl profile image
Brayan Loayza

Thanks bro, you help me a lot..!

Collapse
 
chadsteele profile image
Chad Steele

I'd love it if you wanted to dissect my Redux one line replacement hook... useSync
dev.to/chadsteele/redux-one-liner-...

Collapse
 
mean2me profile image
Emanuele Colonnelli

Hi Phil, I've been trying the runSaga approach but my dispatch is never called... :-/

Collapse
 
seanyboy49 profile image
Sean Lee

I'm not sure if this still relevant, but .done seems to be depracated. Have you tried appending .toPromise() to the end of runsaga ?

Collapse
 
jitendra_gosavi profile image
Jitendra Gosavi

Really helpful article. Thanks Phil! This helped me alot.

Collapse
 
austinknight profile image
Austin Knight

Great overview, its surprising how little info there is on testing sagas this way.

Collapse
 
gabrlucht profile image
Gabriel Luchtenberg

Awesome post!