用 Jest 模拟 ApolloClient 的 client.query 方法

Ant*_*ton 8 unit-testing mocking jestjs graphql apollo-client

2020 年 1 月 22 日更新

@slideshowp2 的解决方案是正确的,但由于这个 TypeError,我根本无法让它工作:

类型错误:无法读取未定义的属性“查询”

好吧,结果是我的玩笑配置已经resetMocks: true设置了。我把它去掉后,测试确实通过了。(虽然我不知道为什么)


原问题:

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

安装程序.ts

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

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 }
}
Run Code Online (Sandbox Code Playgroud)

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

我尝试过以下方法,包括许多其他方法,但均无效。对于这个特定的设置,jest 会抛出

类型错误: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  
  })
}
Run Code Online (Sandbox Code Playgroud)

我认为我遗漏了与这部分相关的内容:

jest.mock('../../api/setup', () => ({
  setupApi: () => jest.fn(),
}))
Run Code Online (Sandbox Code Playgroud)

……但我看不到。

sli*_*wp2 12

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

\n\n

getAssetIdFromService.ts:

\n\n
import { setupApi } from \'./setup\';\nimport { gql } from \'apollo-server\';\n\nconst client = setupApi();\n\nexport const GET_ASSET_ID = gql`\n  query getAssetByExternalId($externalId: String!) {\n    assetId: getAssetId(externalId: $externalId) {\n      id\n    }\n  }\n`;\n\nexport const getAssetIdFromService = async (externalId: string) => {\n  return await client.query({\n    query: GET_ASSET_ID,\n    variables: { externalId },\n  });\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

setup.ts:

\n\n
export const setupApi = (): any => {};\n
Run Code Online (Sandbox Code Playgroud)\n\n

getAssetIdFromService.test.ts:

\n\n
import { getAssetIdFromService, GET_ASSET_ID } from \'./getAssetIdFromService\';\nimport { setupApi } from \'./setup\';\n\njest.mock(\'./setup.ts\', () => {\n  const mApolloClient = { query: jest.fn() };\n  return { setupApi: jest.fn(() => mApolloClient) };\n});\n\ndescribe(\'59829676\', () => {\n  it(\'should query and return data\', async () => {\n    const client = setupApi();\n    const mGraphQLResponse = { data: {}, loading: false, errors: [] };\n    client.query.mockResolvedValueOnce(mGraphQLResponse);\n    const { data, loading, errors } = await getAssetIdFromService(\'e1\');\n    expect(client.query).toBeCalledWith({ query: GET_ASSET_ID, variables: { externalId: \'e1\' } });\n    expect(data).toEqual({});\n    expect(loading).toBeFalsy();\n    expect(errors).toEqual([]);\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
 PASS   apollo-graphql-tutorial  src/stackoverflow/59829676/getAssetIdFromService.test.ts (8.161s)\n  59829676\n    \xe2\x9c\x93 should query and return data (7ms)\n\n--------------------------|----------|----------|----------|----------|-------------------|\nFile                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n--------------------------|----------|----------|----------|----------|-------------------|\nAll files                 |      100 |      100 |      100 |      100 |                   |\n getAssetIdFromService.ts |      100 |      100 |      100 |      100 |                   |\n--------------------------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        8.479s\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n