首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我在努力测试这段残存的传奇

我在努力测试这段残存的传奇
EN

Stack Overflow用户
提问于 2019-04-17 18:58:45
回答 1查看 1.3K关注 0票数 1

我对redux-saga还比较陌生,并且很难测试这段代码:

代码语言:javascript
复制
import { normalize } from 'normalizr';

export function* normalizeResponse(denormalized, schema) {
  const normalized = yield call(normalize, denormalized, schema);
  return normalized;
}

export function* request(apiFn, action, schema) {
  try {
    yield put(requestStart({ type: action.type }));
    const denormalized = yield call(apiFn, action.payload, action.meta);
    const normalized = yield call(normalizeResponse, denormalized, schema);
    yield put(requestSuccess({ type: action.type }));
    return normalized;
  } catch (e) {
    if (__DEV__ && !__TEST__) {
      Alert.alert('Something went wrong');
      console.log(`Error in request saga: ${action.type}`, e);
    }
    if (action.type) {
      const payload = { type: action.type, error: e };
      const meta = action.payload || {};
      yield put(requestFailure(payload, meta));
    }
  }
}

export function* photosShow() {
  while (true) {
    const action = yield take(t.PHOTOS_SHOW);
    const normalized = yield call(request, api.show, action, {
      photo: schema.photo,
    });
    if (normalized) yield put(setEntities(normalized));
  }
}

在网上,我发现了一些redux测试包和一些教程,但它们似乎没有一个比基础更多。下面是这个传奇故事的一步一步的运作方式:

  • photosShow是用一个Flux标准操作调用的,有效载荷为{ id: 1}
  • 这将调用生成器request,这是一个实用函数,用于发出API请求,然后将响应规范化。
  • 首先,将触发requestStart操作。
  • 然后调用api端点。
  • 如果成功,将触发requestSuccess操作。
  • 然后,将使用正常化程序将响应标准化。
  • 然后用setEntities存储在redux状态(回到photosShow中)

任何帮助前进,如何进行这将是非常感谢的。

EN

回答 1

Stack Overflow用户

发布于 2019-05-07 06:54:43

我也很难阅读所有的redux-saga测试资源..。找不到合适的解决方案(至少对我来说是这样)。

我最后的结果是:

  • 我用一个工作的商店“渲染”一个空的回复应用程序。
  • 我手动触发有趣的操作(触发我正在测试的sagas的操作)
  • 我看到了萨迦所消耗的每一个外部资源

最后:我触发了萨加,我发现他们触发了其他的东西。

我认为萨加是一个黑匣子,我检查他们是否尊重与所有其他部分的应用程序的合同。

我以身份验证saga测试为例(我破坏了许多测试良好实践,我知道,它来自于我使用saga的早期测试)(关于renderWithReduxspyUtil函数,请参阅下面):

代码语言:javascript
复制
describe("Login flow with valid credentials", () => {
  let user = "stefano";
  let pwd = "my_super_secret_password";
  let app;
  let spies;
  // const spiedConsole = spyConsole();
  beforeAll(() => {
    app = renderWithRedux(<></>);
    spies = {
      LOGIN_SUCCESS_creator: spyUtil(authActions, "LOGIN_SUCCESS_creator"),
      navigate: spyUtil(ReachRouter, "navigate"),
      postLogin: spyUtil(authNetwork, "postLogin", postLoginOk),
      redirectBackFromLoginPage: spyUtil(navigationData, "redirectBackFromLoginPage")
    };
  });
  test("1 - the login API should be called as soon as the LOGIN_REQUEST action is dispatched", async () => {
    app.store.dispatch(authActions.LOGIN_REQUEST_creator(user, pwd));
    expect(spies.postLogin.spy).toHaveBeenCalledWith(user, pwd);
  });
  test("2 - then when the login API is successfull, a LOGIN_SUCCESS action should be dispatched with the tokens", async () => {
    expect(spies.LOGIN_SUCCESS_creator.spy).toHaveBeenCalledWith(
      expect.any(String),
      expect.any(String)
    );
  });
  test("3 - then the router should be asked to make a redirect to the initial location", async () => {
    expect(spies.redirectBackFromLoginPage.spy).toHaveBeenCalled();
    expect(spies.navigate.spy).toHaveBeenCalledWith(expect.stringMatching(/\//));
  });
  afterAll(() => {
    spies.values().forEach(obj => obj.spy.mockRestore());
    // spiedConsole.mockRestore();
    cleanup();
  });
});

一步一步地:-我用一个工作的Redux+Saga商店呈现一个空的应用程序

代码语言:javascript
复制
app = renderWithRedux(<></>);
  • 我监视萨迦之外的一切
代码语言:javascript
复制
spies = {
      LOGIN_SUCCESS_creator: spyUtil(authActions, "LOGIN_SUCCESS_creator"),
      navigate: spyUtil(ReachRouter, "navigate"),
      postLogin: spyUtil(authNetwork, "postLogin", postLoginOk),
      redirectBackFromLoginPage: spyUtil(navigationData, "redirectBackFromLoginPage")
    };

其中:

  • LOGIN_SUCCESS_creator是一个动作创建者
  • navigate来自Reach路由器
  • postLogin发出AJAX请求(用一个假函数模拟它,几乎立即返回一个“成功”响应(但解决了一个承诺))
  • redirectBackFromLoginPage是一个函数,它再次(在某些条件下)使用navigate实用程序。
代码语言:javascript
复制
- I trigger the `LOGIN_REQUEST` action, and I expect that the AJAX trigger function has been called with the right credentials

代码语言:javascript
复制
test("1 - the login API should be called as soon as the LOGIN_REQUEST action is dispatched", async () => {
  app.store.dispatch(authActions.LOGIN_REQUEST_creator(user, pwd));
  expect(spies.postLogin.spy).toHaveBeenCalledWith(user, pwd);
});
  • 我检查LOGIN_SUCCESS操作是否将与auth令牌一起发送。
代码语言:javascript
复制
test("2 - then when the login API is successfull, a LOGIN_SUCCESS action should be dispatched with the tokens", async () => {
  expect(spies.LOGIN_SUCCESS_creator.spy).toHaveBeenCalledWith(
    expect.any(String),
    expect.any(String)
  );
});
  • 我检查路由器是否被用正确的路由调用(主页的/)
代码语言:javascript
复制
test("3 - then the router should be asked to make a redirect to the initial location", async () => {
  expect(spies.redirectBackFromLoginPage.spy).toHaveBeenCalled();
  expect(spies.navigate.spy).toHaveBeenCalledWith(expect.stringMatching(/\//));
});
  • 然后,我把一切都清理干净
代码语言:javascript
复制
afterAll(() => {
  spies.values().forEach(obj => obj.spy.mockRestore());
  // spiedConsole.mockRestore();
  cleanup();
});

这是“我的”(它来自肯特C.道兹) renderWithRedux函数

代码语言:javascript
复制
// @see https://github.com/kentcdodds/react-testing-library/blob/master/examples/__tests__/react-redux.js
export function renderWithRedux(ui, { initialState, store = configureStore() } = {}) {
  return {
    ...render(
      <div>
        <Provider store={store}>{ui}</Provider>
      </div>
    ),
    // adding `store` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    store
  };
}

其中,configureStore是is的一个函数,它使用各种中间件构建整个Redux商店。

这是我的spyUtil函数

代码语言:javascript
复制
/**
 * A all-in-one spy and mock function
 * @param {object} obj
 * @param {string} name
 * @param {function} mockFunction
 */
export function spyUtil(obj, name, mockFunction = undefined) {
  const spy = jest.spyOn(obj, name);
  let mock;
  if (mockFunction) {
    mock = jest.fn(mockFunction);
    obj[name].mockImplementation(mock);
  }
  return { spy, mock };
}

请注意,这只是身份验证流之一,我没有在这里报告所有的情况。

我想知道你对此的想法

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55734309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档