用Jest模拟ApolloClient的client.query方法

时间:2020-01-20 19:23:11

标签: unit-testing mocking graphql jestjs apollo-client

更新2020年1月22日

@ slideshowp2中的解决方案是正确的,但是由于此TypeError导致我根本无法使用它:

TypeError:无法读取未定义的属性“查询”

原来,这是我开玩笑的配置resetMocks: true的配置。在我删除它之后,测试确实通过了。 (我不知道为什么)


原始问题:

我需要使用Apollo Client在React组件之外的帮助器函数中执行graphql查询,经过一番尝试和错误之后,我采用了这种方法,该方法应该可以正常工作:

setup.ts

export const setupApi = (): ApolloClient<any> => {
  setupServiceApi(API_CONFIG)
  return createServiceApolloClient({ uri: `${API_HOST}${API_PATH}` })
}

getAssetIdFromService.ts

import { setupApi } from '../api/setup'

const client = setupApi()

export const GET_ASSET_ID = gql`
  query getAssetByExternalId($externalId: String!) {
    assetId: getAssetId(externalId: $externalId) {
      id
    }
  }
`

export const getAssetIdFromService = async (externalId: string) => {
  return await client.query({
    query: GET_ASSET_ID,
    variables: { externalId },
  })

  return { data, errors, loading }
}

现在,我正在尝试为getAssetIdFromService函数编写测试测试,但是我很难弄清楚如何让client.query方法在测试中工作。

我尝试了以下方法,包括许多其他无效的方法。 对于此特定设置,笑话会抛出

TypeError:client.query不是函数

import { setupApi } from '../../api/setup'
import { getAssetIdFromService } from '../getAssetIdFromService'

jest.mock('../../api/setup', () => ({
  setupApi: () => jest.fn(),
}))

describe('getAssetIdFromService', () => {
  it('returns an assetId when passed an externalId and the asset exists in the service', async () => {
    const { data, errors, loading } = await getAssetIdFromService('e1')

    // Do assertions  
  })
}

我想我在这部分上缺少一些东西:

jest.mock('../../api/setup', () => ({
  setupApi: () => jest.fn(),
}))

...但是我看不到。

1 个答案:

答案 0 :(得分:3)

您没有正确嘲笑。这是正确的方法:

$("div") - Should return 2 DIVs $("img.some_class") - Should return 1 IMG $("#some_id") - Should return 1 DIV $(".some_class") - Should return 1 DIV and 1 IMG $("input#some_id") - Should return an empty array $("div#some_id.some_class") - Should return 1 DIV $("div.some_class#some_id") - Should return 1 DIV

getAssetIdFromService.ts

import { setupApi } from './setup'; import { gql } from 'apollo-server'; const client = setupApi(); export const GET_ASSET_ID = gql` query getAssetByExternalId($externalId: String!) { assetId: getAssetId(externalId: $externalId) { id } } `; export const getAssetIdFromService = async (externalId: string) => { return await client.query({ query: GET_ASSET_ID, variables: { externalId }, }); };

setup.ts

export const setupApi = (): any => {};

getAssetIdFromService.test.ts

单元测试结果覆盖率100%:

import { getAssetIdFromService, GET_ASSET_ID } from './getAssetIdFromService';
import { setupApi } from './setup';

jest.mock('./setup.ts', () => {
  const mApolloClient = { query: jest.fn() };
  return { setupApi: jest.fn(() => mApolloClient) };
});

describe('59829676', () => {
  it('should query and return data', async () => {
    const client = setupApi();
    const mGraphQLResponse = { data: {}, loading: false, errors: [] };
    client.query.mockResolvedValueOnce(mGraphQLResponse);
    const { data, loading, errors } = await getAssetIdFromService('e1');
    expect(client.query).toBeCalledWith({ query: GET_ASSET_ID, variables: { externalId: 'e1' } });
    expect(data).toEqual({});
    expect(loading).toBeFalsy();
    expect(errors).toEqual([]);
  });
});

源代码:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/stackoverflow/59829676