gpt4 book ai didi

javascript - 如何通过模拟选择器和/或 redux 存储来编写 Redux Saga 测试

转载 作者:行者123 更新时间:2023-11-28 03:12:26 24 4
gpt4 key购买 nike

上下文:我是编写 Redux Saga 测试的新手,并且一直在使用 React Boilerplate开发一个应用程序,它使用 Jest 进行测试。样板文件非常模块化且复杂,我什至不知道如何开始编写测试来模拟选择器并声明我的 Saga 在测试中使用。

在 Saga 中,我使用 Reselect(在“./selectors”文件中)从 reducer 中获取“用户名”和“密码”,并使用 yield select 将它们分配给一个常量>,并使用它来运行 API 调用。我不认为我的问题在于测试传奇,而是模拟传奇中的状态和选择器以模仿登录信息已填写并且可以被从国家手中夺走。

import { takeLatest, call, put, select } from 'redux-saga/effects';
import { loginSuccess, loginFailed } from '../App/actions';
import { ON_LOGIN } from '../App/constants';
import {
makeSelectUsername,
makeSelectPassword,
} from './selectors';
import api from '../../utils/api';

// LISTENER
export default function* loginRequestListener() {
yield takeLatest(ON_LOGIN, login);
}

// WORKER
export function* login() {
const loginParams = {
username: yield select(makeSelectUsername()),
password: yield select(makeSelectPassword()),
isForceLoginAttempt: yield select(makeSelectIsForceLogin()),
};

try {
const user = yield call(api.user.login, loginParams);
yield put(loginSuccess(user));
} catch (error) {
yield put(loginFailed(error.response.data));
}
}

基本上我正在寻找的是一种在测试中运行传奇的方法,以便在传奇中,我可以“强制”loginParams对象使用“fakeState”供选择器使用,因为显然状态不这里不存在:

const fakeState = {username: 'test', password: 'test'}

export function* login() {
const loginParams = {
username: yield select(makeSelectUsername()) // 'test'
password: yield select(makeSelectPassword()) // 'test'
};

我一直在将 redux-saga-tester 作为测试传奇的一种手段,我只是想我不知道从哪里开始模拟我的测试中的状态saga 可以将常量分配给...我想从那里我可以处理剩下的事情。

有人(尤其是使用过样板文件的人)有什么建议吗?

最佳答案

我们在我们的应用程序中使用 redux-saga-tester,我们处理这个问题的方式不是传递一个假状态,我们使用 .next 方法,然后返回我们期望的特定测试结果。请参阅下面的案例来了解我所描述的内容。

const activeOrderId = '1111';

//returns the value for a isConnected boolean
it.next('should get isConnected', (result) => {
expect(result).toEqual(select(getIsConnected));
return true;
});

// returns the value for an activeOrderId
it.next('should get activeOrderId', (result) => {
expect(result).toEqual(select(getActiveOrderId));
return activeOrderId;
});`

这种方法的优点是,您不必为所有传奇故事定义一个大的“假状态”,并且您对每个传奇故事的测试都与之分离。无论如何,您应该对选择器进行单独的测试,以确保它们正常工作。一般而言,saga 测试的一个痛点是,如果您的 saga 中有任何类型的控制流(if/else),那么全面测试所有内容的最佳策略似乎是为该 saga 编写整个其他测试流程。假设你有这个

isConnected = yield select(getIsConnected)
if(isConnected) {
// do x
} else {
// do y
}

我们通过编写两个描述来解决这个问题。一个我们将 isConnected 设置为 true(如上例所示),另一个我们将其设置为 false,如下所示

    //returns the value for a isConnected boolean
it.next('should get isConnected', (result) => {
expect(result).toEqual(select(getIsConnected));
return false;
});

如果您需要将有效负载传递给 saga,您可以使用 sagaHelper 函数来处理它,如下所示

  it.next = sagaHelper(login({
username: 'testUsername',
password: 'testPassword',
// etc
}));

希望有帮助!

关于javascript - 如何通过模拟选择器和/或 redux 存储来编写 Redux Saga 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59976240/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com