Как внедрить зависимости (или контекст) в redux-sagas - PullRequest
0 голосов
/ 21 марта 2019

Как использовать DI в redux-sagas. У меня есть следующая сага

export function* loadUsers() {
  // Want to use something like userService.loadUsers()
}

Как показано в приведенном выше коде, как я могу добавить userService в сагу, в идеале я хотел бы что-то вроде этого

export function* loadUsers(userService) {
   userService.loadUsers()
}

Спасибо

Ответы [ 2 ]

1 голос
/ 07 апреля 2019

Как внедрить зависимости в redux-sagas?

Как использовать DI в redux-sagas?

Вы можете сделать это с помощью Redux saga API, у вас есть доступ к getContext и setContext методам, которые позволяют вам управлять контекстом внутри ваших саг. Посмотрим, как это работает!

Введите ваш контекст

Когда вы звоните createSagaMiddleware, вы можете передать контекст. Позже мы увидим, как получить ваш контекст в ваших сагах

Вот как вставить контекст в redux-saga :

import { createUserService } from "...";
import createSagaMiddleware from "redux-saga";

const userService = createUserService(...);

const sagaMiddleware = createSagaMiddleware({
    context: {
        userService
    }
});

sagaMiddleware.run(rootSaga);

Получите ваш контекст

Вы можете импортировать getContext из redux-saga / Effects и затем вызывать getContext с ключом нужного контекста. Таким образом, вы получите userService в этом случае.

import { getContext } from "redux-saga/effects";

export function* loadUsersSagas(action) {
    const userService = yield getContext("userService");
    const users = yield userService.loadUsers();
    ...
}

Тестирование

Как мы можем протестировать контекст с redux-saga Вы можете использовать redux-saga-test-plan . Цель этой библиотеки - протестировать наши саги.

Что мы хотим сделать?

  • Добавление в наших тестах макета контекста
  • Убедитесь, что мы пытаемся получить правильный элемент в контексте

С provide мы даем [[getContext("userService"), { loadUsers }]], который является поддельным контекстом для userService.

С помощью getContext мы проверяем, получаем ли мы нужный элемент в контексте здесь: userService

import { getContext } from "redux-saga-test-plan/matchers";

describe("Load users", () => {
    it("should load mocked users", () => {
      const loadUsers = () => Promise.resolve([johnDoe]);
      const action = createAction(...);

      return expectSaga(loadUsersSagas, action)
        .provide([[getContext("userService"), { loadUsers }]])
        .getContext("userService")
        .call(...)
        .put(...)
        .run();
    });
});

Надеюсь, мой ответ поможет вам 10

0 голосов
/ 21 марта 2019
export function* loadUsers(userService) {
  userService.loadUsers()
}

в другом месте:

export default function* rootSaga(userService) {
  yield all([
    ...,
    ...,
    loadUsers(userService)
  ]);
}

и затем:

import { createUserService } from "...";
import createSagaMiddleware from "redux-saga";

const userService = createUserService(...);
const sagaMiddleware = createSagaMiddleware();

sagaMiddleware.run(
  rootSaga,
  userService
)
...