簡體   English   中英

如何使用 jest 和酶測試 redux 傳奇

[英]How to test redux saga using jest and enzyme

我有一個傳奇 function 我正在嘗試使用 jest 和酶進行測試,但我遇到了錯誤。 這是我第一次測試 saga 文件,所以我不知道為什么會收到錯誤,即使預期值和接收值是相同的 saga 文件如下:

export const getToken = (state) => state.dextaAuth.token;

export function* setPost(action) {
  try {
    const token = yield select(getToken);
    const data = yield call(
      dextaApiService.post,
      "/api/savedAdvices",
      action.payload,
      token
    );
    yield put(
      openNotification({
        messageType: MessageBarType.success,
        message: "Advice saved successfully",
      })
    );
  } catch (err) {
    yield put(
      openNotification({
        messageType: MessageBarType.error,
        message: `Notification: ${err.message}`,
      })
    );
  }
}

export function* savedAdvicesaga() {
  yield takeLatest(POST_SAVED_ADVICE, setPost);
  yield takeLatest(FETCH_SAVED_ADVICE, fetchSavedAsviceAsync);
}

這是我寫的測試用例:

describe("savedAdviceSaga", () => {
  const genObject = savedAdvicesaga();
  describe("setpost", () => {
    it("should check for post ", async () => {
      const apiResponse = jest
        .spyOn(dextaApiService, "post")
        .mockImplementation(() => Promise.resolve());

      const dispatched = [];
      const action: types.SavedAdviceActionType = {
        type: types.POST_SAVED_ADVICE,
        payload: {
          Title: "test",
          Description: "test dec",
        },
      };
      const iterator = setPost(action);
      const effect = iterator.next().value;
      const expected = select(getToken);
      const result = await runSaga(
        {
          dispatch: (action) => dispatched.push(action),
        },
        setPost,
        action
      );
      expect(effect).toContainEqual(expected);
      expect(apiResponse).toHaveBeenCalledTimes(1);
    });
  });
});

這是我在控制台中遇到的錯誤:

expect(received).toContainEqual(expected) // deep equality

Expected value:  {"@@redux-saga/IO": true, "combinator": false, "payload": {"args": [], 
    "selector": [Function anonymous]}, "type": "SELECT"}
Received object: {"@@redux-saga/IO": true, "combinator": false, "payload": {"args": [], "selector": 
     [Function anonymous]}, "type": "SELECT"}

   27 |         dispatch: (action) => dispatched.push(action),
   28 |       }, setPost, action);
 > 29 |       expect(effect).toContainEqual(expected)
      |                      ^
   30 |       expect(apiResponse).toHaveBeenCalledTimes(1);
   31 |
   32 |     })

您正在使用測試完整的 Saga測試策略。 不需要檢查 saga 的每一步。

運行整個 saga 並斷言預期的效果已經發生。

runSaga(options, saga, ...args)接受getState()選項,以便您提供模擬的 state。 getToken選擇器將使用它。

例如

saga.ts

import { call, put, select, takeLatest } from 'redux-saga/effects';
import { dextaApiService } from './dextaApiService';

export const MessageBarType = {
  success: 'success',
  error: 'error',
};

export function openNotification({ messageType, message }) {
  return { type: messageType, payload: message };
}

export const getToken = (state) => state.dextaAuth.token;

export function* setPost(action) {
  try {
    const token = yield select(getToken);
    const data = yield call(dextaApiService.post, '/api/savedAdvices', action.payload, token);
    yield put(
      openNotification({
        messageType: MessageBarType.success,
        message: 'Advice saved successfully',
      }),
    );
  } catch (err) {
    yield put(
      openNotification({
        messageType: MessageBarType.error,
        message: `Notification: ${err.message}`,
      }),
    );
  }
}

export function* savedAdvicesaga() {
  yield takeLatest('POST_SAVED_ADVICE', setPost);
}

dextaApiService.ts

export const dextaApiService = {
  async post(path, payload, token) {
    return 'real implementation';
  },
};

saga.test.ts

import { setPost } from './saga';
import { dextaApiService } from './dextaApiService';
import { runSaga } from 'redux-saga';
import { Action } from 'redux';

describe('67444295', () => {
  it('should pass', async () => {
    const dispatched: Action[] = [];
    const postSpy = jest.spyOn(dextaApiService, 'post').mockResolvedValueOnce('mocked response');
    const actual = await runSaga(
      {
        dispatch: (action: Action) => dispatched.push(action),
        getState: () => ({ dextaAuth: { token: 'abc123' } }),
      },
      setPost,
      { payload: 'mocked payload' },
    ).toPromise();
    expect(postSpy).toBeCalledWith('/api/savedAdvices', 'mocked payload', 'abc123');
    expect(dispatched).toEqual([{ type: 'success', payload: 'Advice saved successfully' }]);
    postSpy.mockRestore();
  });
});

測試結果:

 PASS  src/stackoverflow/67444295/saga.test.ts
  67444295
    ✓ should pass (5 ms)

--------------------|---------|----------|---------|---------|-------------------
File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------------|---------|----------|---------|---------|-------------------
All files           |   85.71 |        0 |      60 |      80 |                   
 dextaApiService.ts |      50 |      100 |       0 |      50 | 3                 
 saga.ts            |   89.47 |        0 |      75 |   84.62 | 26,36             
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.567 s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM