【问题标题】:How to mock http request in sagas (black box testing approach)如何在 sagas 中模拟 http 请求(黑盒测试方法)
【发布时间】:2018-02-09 07:13:02
【问题描述】:

我正在尝试采用黑盒方法并使用 sagaTester 来测试我的 sagas。

这是来自 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);
  });

这是我遇到的错误:

错误:超时 - 未在超时内调用异步回调 由 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定。

我要做的就是模拟来自这一行的响应:

const repos = yield call(request, requestURL);

我做错了什么????

感谢任何帮助!!!

【问题讨论】:

    标签: javascript reactjs unit-testing redux saga


    【解决方案1】:

    yout 代码的两个主要问题是:

    • 缺少 CORS 标头
    • 错误的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);
    

    【讨论】:

    • 谢谢,但这没有用。我希望 nock 能够模拟呼叫和响应,以便'yield put(reposLoaded(repos, username));' reposLoaded 动作将被调度。但这从未发生过。如果有人拿起什么是错的,请告诉我!!!还是卡住了..
    • @calpang 是的,我又错过了 2 个错误......我已经更新了我的答案。希望对你有帮助!
    【解决方案2】:

    我希望这将帮助其他遇到此问题的人。 这里的问题是 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 来模拟请求。经过几个小时的摆弄,终于得到了这个工作。感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-27
      • 2019-08-19
      • 1970-01-01
      • 2012-07-09
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多