【问题标题】:Testing Apollo Mutation graphql errors测试 Apollo Mutation graphql 错误
【发布时间】:2019-06-12 02:11:18
【问题描述】:

根据docs,我应该能够模拟graphql错误以进行测试。

To simulate GraphQL errors, simply define errors along with any data in your result.

const dogMock = {
  // ...
  result: {
    errors: [{ message: "Error!" }],
  },
};

但是该错误导致我的测试完全失败。它对查询按预期工作,但docs 说它对突变也一样工作。

为了简单起见,mutations 的错误案例在这里没有展示,但是测试 Mutation 错误与测试 Query 错误完全相同:只需向 mock 中添加一个错误,触发该 mutation,然后检查 UI用于错误消息。

这是我的代码...

组件

class Example extends Component {
  state = {email: ''};

  render() {
    return (
      <div>
        <Mutation mutation={EXAMPLE_MUTATION} variables={this.state}>
          {(signin, {error, loading}) => {
            if(error)
              return <p data-test="graphql-error">{error.message}</p>;

            return (
              <form method="post" onSubmit={async e => {
                e.preventDefault();
                await signin();
                this.setState({email: ''});
              }}>
                <fieldset disabled={loading} aria-busy={loading}>
                  <label htmlFor="email">
                    Email
                    <input type="email" name="email" placeholder="email" value={this.state.email} onChange={this.saveToState} />
                  </label>
                  <div>
                    <input type="submit" value="Example"/>
                  </div>
                </fieldset>
              </form>
            )
          }}
        </Mutation>
      </div>
    );
  }

  saveToState = e => this.setState({[e.target.name]: e.target.value});
}

变异

const EXAMPLE_MUTATION = gql`
  mutation EXAMPLE_MUTATION($email: String!){
    example(email: $email){
      email
      name
    }
  }
`;

测试


describe('<Example />', () => {
  it('handles errors properly', async () => {
    const wrapper = mount(
      <MockedProvider mocks={[{
        request: {query: EXAMPLE_MUTATION, variables: {email: 'test@email.com'}},
        result: {errors: [{message: "There was an error"}]}}]}>
        <Example />
      </MockedProvider>
    );

    type(wrapper, 'email', 'test@email.com');
    wrapper.update();
    wrapper.find(`form`).simulate('submit');

    // form is busy + contains inputs
    expect(toJSON(wrapper.find('form'))).toMatchSnapshot();

    await wait();
    wrapper.update();

    // test fails before ever getting here

    const err = wrapper.find('[data-test="graphql-error"]');
    expect(err.text()).toEqual('There was an error');

    console.log(err.debug())
    console.log(err.text())
  });

测试因我的错误而失败,而不是像我预期的那样将其呈现到页面上。

    GraphQL error: There was an error

      at new ApolloError (node_modules/src/errors/ApolloError.ts:56:5)
      at Object.next (node_modules/src/core/QueryManager.ts:258:21)
      at notifySubscription (node_modules/zen-observable/lib/Observable.js:130:18)
      at onNotify (node_modules/zen-observable/lib/Observable.js:165:3)
      at SubscriptionObserver.next (node_modules/zen-observable/lib/Observable.js:219:7)
      at node_modules/react-apollo/test-utils.js:937:38
      at Timeout.callback (node_modules/jsdom/lib/jsdom/browser/Window.js:678:19)

我哪里做错了?任何帮助将不胜感激!

【问题讨论】:

    标签: reactjs jestjs react-apollo


    【解决方案1】:

    当突变失败时,如果没有onError 属性提供给Mutation 组件(source code here),react-apollo 会抛出错误。如果您未捕获错误,则测试运行程序会将其解释为失败的测试。

    这可以通过提供一个虚拟的onError 道具来防止错误抛出来解决:

    <Mutation mutation={EXAMPLE_MUTATION} variables={this.state} onError={() => {}}>
    

    或通过将突变调用包装在 try...catch 中(await 很重要,因为错误是异步的):

    try {
      await signin();
    } catch (error) {
      // do smth with the error here
    }
    

    有一个相关的GitHub issue

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 2022-01-27
      • 2018-08-26
      • 2020-10-05
      • 2020-12-01
      • 2021-05-30
      • 2018-07-15
      • 2020-10-26
      • 2017-06-23
      相关资源
      最近更新 更多