在查询中使用片段时,Apollo Boost MockedProvider returns 空对象

Apollo Boost MockedProvider returns empty object when using fragment on query

我有一个使用 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 returns 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",
...
}

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

read more here