如何在 sagas 中模拟 http 请求(黑盒测试方法)
How to mock http request in sagas (black box testing approach)
我正在尝试采用黑盒方法并使用 sagaTester 来测试我的传奇。
这是来自 react-boilerplate 的 saga.js:
export function* getRepos() {
// Select username from store
const username = yield select(makeSelectUsername());
const requestURL = `https://api.github.com/users/${username}/repos?type=all&sort=updated`;
try {
// Call our request helper (see 'utils/request')
const repos = yield call(request, requestURL);
yield put(reposLoaded(repos, username));
} catch (err) {
yield put(repoLoadingError(err));
}
}
export default function* githubData() {
// Watches for LOAD_REPOS actions and calls getRepos when one comes in.
// By using `takeLatest` only the result of the latest API call is applied.
// It returns task descriptor (just like fork) so we can continue execution
// It will be cancelled automatically on component unmount
yield takeLatest(LOAD_REPOS, getRepos);
}
这是我的 saga.test.js:
it('black box testing using sagaTester', async () => {
const initialState = fromJS({
home: {
username: 'john',
},
});
const sagaTester = new SagaTester({ initialState });
sagaTester.start(githubData);
sagaTester.dispatch(loadRepos());
nock('https://api.github.com/repos?type=all&sort=updated')
.get('/users/john')
.reply(200, 'hello world');
await sagaTester.waitFor(reposLoaded.type);
});
这是我遇到的错误:
Error: Timeout - Async callback was not invoked within timeout
specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
我想做的就是模拟这一行的响应:
const repos = yield call(request, requestURL);
我做错了什么????
感谢任何帮助!!!
您的代码的主要 2 个问题是:
- 缺少 CORS header
- 打错了
waitFor
电话
工作示例:
nock('https://api.github.com')
.get('/users/john/repos')
.query({ type: "all", sort: "updated" })
.reply(200, [{ name: 'First repo', }, { name: 'Second repo', }], {'Access-Control-Allow-Origin': '*'});
await sagaTester.waitFor(reposLoaded().type);
我希望这对遇到此问题的其他人有所帮助。
这里的问题是 whatwg-fetch,它是在 react-boiler-plate 库中烘焙的。
我查看了示例 here,我注意到正在使用 node-fetch。
所以我替换了这一行:
const repos = yield call(request, requestURL);
与:
const repos = yield call(() => fetch(requestURL));
我的测试成功了。
另一件事,如果你想使用axios而不是whatwg,那么你最好使用axios-mock-adapter来模拟请求。经过数小时的摆弄,终于得到了这个工作。感谢您的帮助!
我正在尝试采用黑盒方法并使用 sagaTester 来测试我的传奇。
这是来自 react-boilerplate 的 saga.js:
export function* getRepos() {
// Select username from store
const username = yield select(makeSelectUsername());
const requestURL = `https://api.github.com/users/${username}/repos?type=all&sort=updated`;
try {
// Call our request helper (see 'utils/request')
const repos = yield call(request, requestURL);
yield put(reposLoaded(repos, username));
} catch (err) {
yield put(repoLoadingError(err));
}
}
export default function* githubData() {
// Watches for LOAD_REPOS actions and calls getRepos when one comes in.
// By using `takeLatest` only the result of the latest API call is applied.
// It returns task descriptor (just like fork) so we can continue execution
// It will be cancelled automatically on component unmount
yield takeLatest(LOAD_REPOS, getRepos);
}
这是我的 saga.test.js:
it('black box testing using sagaTester', async () => {
const initialState = fromJS({
home: {
username: 'john',
},
});
const sagaTester = new SagaTester({ initialState });
sagaTester.start(githubData);
sagaTester.dispatch(loadRepos());
nock('https://api.github.com/repos?type=all&sort=updated')
.get('/users/john')
.reply(200, 'hello world');
await sagaTester.waitFor(reposLoaded.type);
});
这是我遇到的错误:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
我想做的就是模拟这一行的响应:
const repos = yield call(request, requestURL);
我做错了什么????
感谢任何帮助!!!
您的代码的主要 2 个问题是:
- 缺少 CORS header
- 打错了
waitFor
电话
工作示例:
nock('https://api.github.com')
.get('/users/john/repos')
.query({ type: "all", sort: "updated" })
.reply(200, [{ name: 'First repo', }, { name: 'Second repo', }], {'Access-Control-Allow-Origin': '*'});
await sagaTester.waitFor(reposLoaded().type);
我希望这对遇到此问题的其他人有所帮助。 这里的问题是 whatwg-fetch,它是在 react-boiler-plate 库中烘焙的。
我查看了示例 here,我注意到正在使用 node-fetch。
所以我替换了这一行:
const repos = yield call(request, requestURL);
与:
const repos = yield call(() => fetch(requestURL));
我的测试成功了。
另一件事,如果你想使用axios而不是whatwg,那么你最好使用axios-mock-adapter来模拟请求。经过数小时的摆弄,终于得到了这个工作。感谢您的帮助!