【问题标题】:Apollo Boost MockedProvider returns empty object when using fragment on queryApollo Boost MockedProvider 在查询中使用片段时返回空对象
【发布时间】:2020-12-10 23:31:46
【问题描述】:

我有一个使用 Apollo Boost MockedProvider、Jest 和 React 测试库的工作测试,当我将返回的字段更改为 graphQL fragment 时,它停止工作。我错过了什么?

TicketGql.js

export default class TicketGql {
  static VIEW_FRAGMENT = gql`
    fragment ViewFragment on View {
      viewId
      versionId
      name
      description
      orderedColumns {
        columnId
        name
        descriptions {
          translationId
          lang
          description
        }
      }
    }
  `;

  static GET_TICKET_VIEW = gql`
    query getView($viewId: ID!) {
      view(viewId: $viewId) {
        viewId
        versionId
        name
        description
        orderedColumns {
          columnId
          name
          descriptions {
            translationId
            lang
            description
          }
        }
      }
    }
  `;
}

TicketGql.test.js

...
it('GET_TICKET_VIEW', async () => {
  const currentLang = uniqid('lang_');
  const viewMock = {
    viewId: uniqid('viewId_'),
    versionId: uniqid('versionId_'),
    name: uniqid('name_'),
    description: uniqid('description_'),
    orderedColumns: [],
  };
  _.times(_.random(1, 5), (columnIndex) => {
    viewMock.orderedColumns.push({
      columnId: uniqid('columnId_'),
      name: uniqid('columnId_'),
      descriptions: [],
    });
    _.times(
      _.random(1, 3),
      (descIndex) => viewMock.orderedColumns[columnIndex].descriptions.push({
        translationId: uniqid('translationId_'),
        lang: descIndex === 0 ? currentLang : uniqid('lang_'),
        description: uniqid('description_'),
      }),
    );
  });
  const variables = { viewId: viewMock.viewId };
  const mocks = [
    {
      request: {
        query: TicketGql.GET_TICKET_VIEW,
        variables,
      },
      result: {
        data: {
          view: viewMock,
        },
      },
    },
  ];
  const TicketViewColumns = () => {
    const { data, loading, error } = useQuery(TicketGql.GET_TICKET_VIEW, {
      variables,
    });
    return (
      <div>
        {error}
        <ul>
          {
            loading
              ? 'loading...'
              : (
                data.view.orderedColumns.map((column) => (
                  <li key={column.columnId}>
                    {column.descriptions.find((d) => d.lang === currentLang).description}
                  </li>
                ))
              )
          }
        </ul>
      </div>
    );
  };
  render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <TicketViewColumns />
    </MockedProvider>,
  );
  await waitFor(() => expect(screen.queryAllByRole('listitem'))
    .toHaveLength(viewMock.orderedColumns.length));
 );
...

此测试按原样运行。但是,当我将 GET_TICKET_VIEW 更改为此...

static GET_TICKET_VIEW = gql`
  query getView($viewId: ID!) {
    view(viewId: $viewId) {
      ...ViewFragment
    }
  }
  ${TicketGql.VIEW_FRAGMENT}
`;

...它只是停止工作。 MockedProvide 返回data === { view: {} } 而不是viewMock 中提供的数据,导致data.view.orderedColumns.map 出错,因为data.view.orderedColumnsundefined。我在一个突变上使用这个片段进行了另一个测试,它可以工作。

编辑:

package.json

"dependencies": {
  "@apollo/react-hooks": "^4.0.0",
  "apollo-boost": "^0.4.9",
  "graphql": "^15.0.0",
  ...
}
"devDependencies": {
  "@apollo/client": "^3.1.1",
  "@testing-library/jest-dom": "^5.8.0",
  "@testing-library/react": "^10.0.4",
...
}

【问题讨论】:

    标签: jestjs graphql react-apollo react-testing-library


    【解决方案1】:

    当您使用片段时,只需将__typename 添加到您的模拟对象。 没有片段/联合的简单查询不需要它,但如果你有它就需要它。

    read more here

    【讨论】:

    • 现在我倾向于在我的模拟对象生成器中添加__typename,并将其作为我的 TypeScript 类型中的可选字段。这样我就可以一直得到正确的__typename,这样我就可以在 graphql 和非 graphql 上下文之间共享我的模拟工厂。我还可以从查询中复制粘贴实际数据来构建这些模拟。这对 GraphQL 模式类型产生了轻微的新依赖,但它可能是值得的。
    猜你喜欢
    • 2021-02-16
    • 2019-04-02
    • 1970-01-01
    • 2021-11-12
    • 2013-07-06
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2018-10-17
    相关资源
    最近更新 更多