У меня есть сага с функциями выбора, которые должны брать пару информации из состояния и использовать их для перехода к новому URL-адресу.
КОД ДЛЯ SAGA:
export function* appRedirectToNewTopic() {
const getCreatingNewTopicError = yield select(getCreatingTopicError);
const newTopicId = yield select(getNewTopicId);
const groupId = yield select(getGroupId);
if (isEmpty(getCreatingNewTopicError)) { // this is lodash isEmpty
yield put(push(getRouteUrl(routerUrls.TOPIC_CHAT.url, {
groupId,
topicId: newTopicId,
})));
} // TODO add here when notification is made
}
КОД ДЛЯ ТЕСТА SAGA:
describe('appRedirectToNewTopic', () => {
const action = appCreateNewTopicFinishedAction();
const generator =
cloneableGenerator(appRedirectToNewTopic)(action);
const expectedGroupId = {
apiGroups: {
groupInfo: {
groupInfo: {
id: 466,
},
},
},
};
const expectedTopicId = {
apiTopics: {
newTopicId: 22466,
},
};
let topicId;
let groupId;
it('should return empty error', () => {
expect(generator.next().value)
.toEqual(select(getCreatingTopicError));
});
it('should return new topicId', () => {
topicId = generator.next(expectedTopicId).value;
expect(topicId)
.toEqual(select(getNewTopicId));
});
it('should return groupId', () => {
groupId = generator.next(expectedGroupId).value;
expect(groupId)
.toEqual(select(getGroupId));
});
it('should redirect user to new topic screen', () => {
expect(generator.next().value)
.toEqual(put(push(getRouteUrl(routerUrls.TOPIC_CHAT.url, {
groupId,
topicId,
}))));
});
});
Ошибка, которую я получаю, должна перенаправить пользователя в новую тему, а ошибка - Expected value to equal:
{"@@redux-saga/IO": true, "PUT": {"action": {"payload": {"args": ["/chat/[object Object]/[object Object]"], "method": "push"}, "type": "@@router/CALL_HISTORY_METHOD"}, "channel": null}}
Received:
undefined
.
Значение, которое вы передаете следующему методу, - это то, что должен дать текущий yield
, а не тот, который вы тестируете с равным после этого. Попробуй это:
describe('appRedirectToNewTopic', () => {
const action = appCreateNewTopicFinishedAction();
const generator =
cloneableGenerator(appRedirectToNewTopic)(action);
const expectedGroupId = {
apiGroups: {
groupInfo: {
groupInfo: {
id: 466,
},
},
},
};
const expectedTopicId = {
apiTopics: {
newTopicId: 22466,
},
};
let topicId;
let groupId;
it('should return empty error', () => {
expect(generator.next().value)
.toEqual(select(getCreatingTopicError));
});
it('should return new topicId', () => {
topicId = generator.next().value;
expect(topicId)
.toEqual(select(getNewTopicId));
});
it('should return groupId', () => {
groupId = generator.next(expectedTopicId).value;
expect(groupId)
.toEqual(select(getGroupId));
});
it('should redirect user to new topic screen', () => {
expect(generator.next(expectedGroupId).value)
.toEqual(put(push(getRouteUrl(routerUrls.TOPIC_CHAT.url, {
groupId,
topicId,
}))));
});
});
Это не что-то конкретное для саг, а генераторы в целом. Я предлагаю просто немного поиграть с генераторами - вы также можете прочитать о них на популярных сайтах, таких как MDN. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
Тем не менее, я постараюсь объяснить проблему дальше. Важно помнить, какая часть генератора в какой момент выполняется. Когда вы создаете генератор, ни один из кодов внутри не выполняется, при первом вызове next
генератор начинает выполняться с начала до первого yield. Значение, которое вы получаете от первого вызова next()
, - это то, что принесла первая доходность. Теперь, когда вы вызываете next
во второй раз, вы можете передать ему значение, и оно будет использоваться вместо первого выражения yield, затем функция продолжит выполнение с этим новым значением до второго yield и т. д.
Спасибо Мартин :)
Спасибо Мартин. Это сработало. Если честно, я не понял, почему это сработало. Не могли бы вы подробнее объяснить свой ответ или указать мне какой-нибудь материал для чтения. извините, я могу дать вам только 25 пинт. Я бы дал вам больше, если бы мог :)