testing - 酶集成测试:axios.get 调用未在 redux-saga 中执行
问题描述
我正在尝试为一些触发 redux 传奇的动作创建者设置测试。
我的传奇从本地烧瓶服务器检索一个词(将始终返回相同的词),然后显示该词。这不是我的真实案例,但我试图从简单的事情开始......
当我在我的反应应用程序中使用按钮触发它们时,我的动作创建者和传奇按预期工作(该词是从服务器检索的,存储在我的 redux 存储中,并在我的反应组件中使用选择器显示),但我无法获得测试成功。
我只想测试 redux 部分,而不是实际渲染的 react 组件(不确定这是否是我的问题的一部分)
我使用 Enzyme 进行测试,我的商店已正确创建并且可以发送操作。我还可以看到我的 saga 正在使用控制台日志调用:
我的测试代码:
import { Store } from 'redux';
import { RootState } from '../root.reducer';
import { storeFactory } from '../../../test/testUtils';
import { getSecretWord } from './secret-word.actions';
describe('getSecretWord action creator', () => {
let store: Store<RootState>;
beforeEach(() => {
store = storeFactory();
});
test('add response word to state', () => {
const secretWord = 'party';
store.dispatch(getSecretWord());
const newState = store.getState();
console.log('new state: ' + newState.secretWord);
expect(newState.secretWord).toBe(secretWord);
});
});
和我的传奇功能:
export function* getSecretWordSaga(action: getSecretWordAction): Generator<ForkEffect | CallEffect | PutEffect, void, unknown>
{
try {
console.log('getSecretWordSaga() saga started');
console.log('before axios query call:');
const response:any = yield call(api.get, '/api/word');
// const response = {data: { word: 'party'}, status:200}
console.log('axios query returned: ');
console.log(response);
yield put(setSecretWord(response.data.word));
console.log('getSecretWordSaga() saga finsshed');
} catch (err) {
console.log('error occured:');
console.log(err);
console.log('getSecretWordSaga() saga finsshed with errors');
}
}
export function* getSecretWordSagaStart(): Generator<
ForkEffect<never>,
void,
unknown
> {
yield takeLatest(SecretWordActionTypes.GET_SECRET_WORD, getSecretWordSaga);
}
axios api 非常基础,它包括两个用于日志记录的拦截器:
import axios from 'axios';
export const api = axios.create({
baseURL: 'http://localhost:5000',
responseType: 'json',
});
api.interceptors.request.use(request => {
console.log('Starting Request', JSON.stringify(request, null, 2))
return request
})
api.interceptors.response.use(response => {
console.log('Response:', JSON.stringify(response, null, 2))
return response
})
我可以在日志中(在“npm test”中)看到“在 axios 查询调用之前”这一行的日志和一个用于请求拦截器的 console.log(那里一切看起来都很好),但之后没有更多日志(两者都没有成功或错误)
如果我注释掉“yield call..”并对响应进行硬编码(就像下面注释掉的行),我的传奇故事会一直结束并且我的测试成功。
为什么没有执行 yield Call(api.get, '/api/word') (而且我没有收到任何错误消息)?
我认为该代码是正确的,因为它在 react 中执行时运行良好。我的烧瓶服务器显然也在运行,我可以在烧瓶应用程序中看到正在运行的测试没有调用 api。
我显然打算模拟那个 api 调用,但在那里也遇到了一些问题,这就是为什么我首先想让真正的 api 调用工作。
解决方案
在尝试了许多不同的方法来添加超时之后,将测试功能设置为异步并在 Promise 中添加 setTimeout 确实有效。这并不理想,因为我必须将超时设置为特定值,但我想不出更好的方法来让它工作。
test("add response word to state", async () => {
const secretWord = 'party';
store.dispatch(getSecretWord());
await new Promise(res => setTimeout(res, 1000));
const newState = store.getState();
console.log('new state: ' + newState.secretWord);
expect(newState.secretWord).toBe(secretWord);
});
推荐阅读
- r - 使用 R 中的 data.table 进行分组条件过滤
- postgresql - 在 PostgreSQL 中使用数组或 json 格式化字符串列
- reactjs - jss-snapshot-serializer:jss 嵌套选择器或@media 查询不会添加到 json 快照 (JEST)
- python - 在 Pandas Dataframe 中获取具有非零列的前 11 行
- javascript - 将 (number | number[]) 转换为 number[]
- git - 如何使用 git 忽略自动生成的文件?
- microsoft-teams - 在团队桌面、Web 和移动应用程序中呈现 AdaptiveCard 的差异,其中列样式未在前两个应用程序中应用。一个错误?
- android - Mantra 生物识别设备在扫描后无法获取数据(Android 集成)
- javascript - 新添加的元素在js中效果不好,为什么?
- snowflake-cloud-data-platform - 雪花函数创建