Не могу выполнить модульный тест redux-saga с функцией селектора, используя Jest

1

Проблема Объяснение:

Я хочу, чтобы подразделение тестировало саму саму с помощью Jest. Я делаю это так, как описано в примере, представленном в документах redux-saga: https://redux-saga.js.org/docs/advanced/Testing.html

В моей саге я selectSet функцию selectSet которая возвращает определенный объект из хранилища приложений:

export const selectSet = state => state.setStore.set

В моей саге я пытаюсь выполнить эту функцию селектора:

import { put, select } from 'redux-saga/effects'
import { selectSet } from '../selectors'

export function* getSet() {
  try {
    const set = yield select(selectSet)
    yield put({ type: 'SET_SUCCESS', payload: { set } })
  } catch (error) {
    yield put({ type: 'SET_ERROR', payload: { error } })
  }
}

В моем тесте нет действительного хранилища приложений, поэтому мне пришлось бы издеваться над функцией, чтобы вернуть ожидаемый объект:

import assert from 'assert'
import * as AppRoutines from './AppRoutines'
import { put, select } from 'redux-saga/effects'

describe('getSet()', () => {
    it('should trigger an action type "SET_SUCCESS" with a payload containing a valid set', () => {
        const generator = AppRoutines.getSet()

        const set = {
          id: 1,
          slots: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
        }

        const selectSet = jest.fn()
        selectSet.mockReturnValue(set)

        // Saga step 1
        const actualFirst = generator.next().value
        const expectedFirst = select(selectSet)

        assert.deepEqual(
          actualFirst,
          expectedFirst,
          'it should retreive a valid set from the store using the selectSet selector'
        )
    })
})

Однако, если я утверждаю, что сага возвращает определенное значение генератора с помощью функции deepEqual и моей издевательства, она ожидает, что моя функция выбора будет иметь исходный конструктор selectSet. Но поскольку я издеваюсь над функцией с jest.fn(), конструктор на самом деле равен mockConstructor что делает мой тест неудачным:

Expected value to deeply equal to:
    {"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function mockConstructor]}}
Received:
    {"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function selectSet]}}

Вопрос: Как я могу сделать assert.deepEqual, содержащий функцию mock без противоречивых типов конструкторов?

Альтернативный вопрос: Есть ли способ заставить мое утверждение ожидать mockConstructor вместо фактического конструктора selectSet?

Теги:
unit-testing
react-redux
redux-saga
jest

1 ответ

4
Лучший ответ

Вам не нужно вообще издеваться над селектором, так как в таком сага-тест такого селектора никогда не назовешь, вместо этого вы проверяете декларативные инструкции, которые создаются для промежуточного программного обеспечения сокращения саги, чтобы действовать так, как вы ожидаете

Это инструкция, что сага создаст {"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function selectSet]}}, но в качестве промежуточного программного обеспечения не запускается во время этого тестового сценария selectSelect никогда не будет вызван

Если вам нужно высмеять результаты, которые ваш селектор вернет для вашего действия, тогда вы сделаете это, передав макет данных в следующий шаг...

    const set = {
      id: 1,
      slots: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
    }

    // Saga step 1
    const firstYield = generator.next().value
    assertDeepEqual(firstYield, select(selectSet))

    // Step 2 - successful so dispatch action
    // mock data from the previous yield by passing into this step via 'next(stubbedYieldedData)'
    const secondYield = generator.next(set).value
    assertDeepEqual(secondYield, put({type: 'SET_SUCCESS', payload: {set} }))
  • 0
    идеальный! Спасибо :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню