在testcafe中模拟阿波罗查询

时间:2020-01-21 16:30:02

标签: mocking graphql apollo e2e-testing testcafe

我目前正在使用testcafe进行e2e测试。

由于testcafe不支持异步代码,因此我必须模拟graphql查询。

除了使用RequestMock函数以外,还有其他方法吗?

它不是真正对开发人员友好的,因为它非常注重REST?

编辑:

关于我的testcafe不允许使用异步代码的事实,以下是一些详细信息:如果我尝试使用异步代码(查询实际数据),则setBody函数会丢失。有一个问题here

const handler = async (req, res) => {


 // ok
  res.setBody('foobar')
  data = await Promise.resolve({ some: 'data' })
  // setBody is no longer defined
  res.setBody(JSON.stringify(data))
}
fixture('Register')
.page('http://foobar/register')
.requestHook(handler)

编辑2:

我添加了我当前正在使用的两个文件。

请在导出默认值之前查看apolloHook.js

// apolloHook.js
import { RequestMock } from 'testcafe'
import fetch from 'node-fetch'
import gql from 'graphql-tag'
import configureApolloClient from '../../../src/ApolloClient'
const urlToCatch = 'http://127.0.0.1/index.php/graphql/'
const client = configureApolloClient({
  uri: 'http://nginx/index_test.php/graphql/',
  fetch
})
const handler = async (req, res) => {
  const body = JSON.parse(req.body.toString('utf8'))
  const query = gql`${body.query}`
  const { variables } = body
  let data = null
  if (body.query.startsWith('query')) {
    data = await client.query({ query, variables })
  } else {
    data = await client.mutate({ mutation: query, variables })
  }

  // res.setBody is undefined !

  res.setBody(JSON.stringify(data))
}
export default RequestMock()
  .onRequestTo({ url: urlToCatch, method: 'POST' })
  .respond(handler)
// register.js
import { Selector } from 'testcafe'
import { REGISTER_FIXTURES } from '../fixtures'
import { testInput, testPhoneInput, testCountryInput, testCountriesInput, testSelect } from '../utils/utils'
import apolloHook from '../utils/apolloHook'
const registerUrl = 'http://front:3000'
//Uncomment for local testing
//const registerUrl = 'http://127.0.0.1:3000'
fixture('Register')
  .page(registerUrl)
  .requestHooks(apolloHook)
test('Fill out sign up', async t => {
  await testInput(t, Selector('[data-testid=\'email\']'), 'john.doe@professional.com')
  await t
    .click(Selector('[data-testid=\'send-me-a-code\']'))
    .expect(Selector('[data-testid=\'one-time-password-button\']').innerText).eql('Submit')
})

1 个答案:

答案 0 :(得分:0)

我很确定,您已经找到了解决方案,因为testcafe本身在async/await钩子内支持respond

您还可以尝试使用RequestMock和该库提供的一些自定义方法在运行时testcafe-graphql-mock库中模拟您的graphql查询。

将此库添加为dev-dependency

npm i -D testcafe-graphql-mock

现在,您可以使用自定义命令:

import { mockGraphQL } from 'testcafe-graphql-mock';
 
// define the schema
const schema = `
type Person {
  firstname: String!
  surname: String!
}
 
type Query {
  people: [Person]
}
`;
 
// define the mock
const mock = {
  Query: () => ({
    people: () => [
      {
        firstname: 'Lee',
        surname: 'Byron',
      },
    ],
  }),
};
 
// create traditional testcafe request mock
const requestMock = RequestMock()
  .onRequestTo({ url: 'http://localhost:3000/graphql', method: 'POST' })
  .respond(async (req, res) => {
    await mockGraphQL(
      {
        schema,
        mock,
      },
      req,
      res
    );
  });
 
// now call the testcafe request mock in fixures as request hooks
fixture(`GraphQL Mock test`)
  .page('http://localhost:3000/')
  .requestHooks(requestMock);
 
test('test graphql mock data', async (t) => {
  await t.click(Selector('button'));
  await expect(Selector('div')).contains('Lee Byron');
});

您还可以将delay添加到响应中:

await mockGraphQL(
      {
        schema,
        mock,
        delay: 5000,
      },
      req,
      res
    );