2

I'm trying to test Sagas with Jest, but I can't make Sagas call the loginApi mocked function, It seems that it is calling the actual function. Can someone help me with this?

That's my saga:

export async function loginApi(user) {
  return await api.post('/auth/customers/login', {
    email: user.email, //customer1@mi.me
    password: user.password, //12345678
  });
}

// Saga function that handles the side effect when the loginWatcher is triggered
export function* loginActionEffect(loginAction) {
  //console.tron.log('login Action Effect');

  try {
    const response = yield call(loginApi, loginAction.user);
    // console.log('response:' + response);

    yield AsyncStorage.setItem('access_token', response.data.access_token);
    yield put(LoginActions.setLogin(loginAction.user));
    yield put(LoginActions.setError(''));
  } catch (e) {
    //console.log('problema com o login!');
    yield put(LoginActions.setError('Email ou senha incorretos!'));
  }
}

That's my test:

it('should receive token in case of success', async () => {
    const mockToken = {token: 'kaajfalkfjlaniurvayeg'};
    const loginApi = jest.fn().mockImplementation(() => Promise.resolve(mockToken));
    const dispatched = [];

    const result = await runSaga(
      {
        dispatch: action => dispatched.push(action),
      },
      loginActionEffect,
    );

    expect(loginApi).toHaveBeenCalled();
    expect(dispatched).toContainEqual(Creators.setLogin());
    expect(dispatched).toContainEqual(Creators.setError());
    loginApi.mockClear();
  });

And that's my test result:

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

  21 |     );
  22 | 
> 23 |     expect(loginApi).toHaveBeenCalled();
     |                      ^
skyboyer
  • 22,209
  • 7
  • 57
  • 64
n3n3
  • 288
  • 1
  • 7
  • 1
    Hmm, but why do you want to test your saga this way? The cool thing about declarative effects is that you can test them using simple equality checks w/o performing any actual effect and mocking things. – Yury Tarabanko Jan 15 '20 at 16:09
  • I suggest you take a look on the docs on how to test sagas. – gadi tzkhori Jan 15 '20 at 16:35

1 Answers1

2

runSaga returns a Task object not a Promise so you need to call toPromise

const result = await runSaga(
  {
    dispatch: action => dispatched.push(action),
  },
  loginActionEffect,
).toPromise();

PS. Your way of testing sagas goes against recommended. Please read this docs. As I have written in my comment. One cool thing about declarative effects is that effect execution relies on interpreter. So you don't need to actually perform or mock anything in your tests.

Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98