【问题标题】:How to validate graphql schema with fragmented documents如何使用碎片化文档验证 graphql 模式
【发布时间】:2020-05-09 05:59:43
【问题描述】:

我认为在单元测试级别支持架构验证会很酷,这样我们就可以在升级 api 时意识到对查询的重大更改

我想设置测试,以便它支持自动发现任何新的 *.graphql 文件,但这样做,开玩笑的过程认为当前工作目录在 __tests__ 所以当我评估 graphql使用加载器手动记录文档,这样的查询中的相关片段失败:

#import "./fragments/FullUserData.graphql"

query User(
  $zid: String!
) {
  user {
    userData: get(
      zid: $zid
    ) {
      ...FullUserData
    }
  }
}

失败信息:

Error: Cannot find module './fragments/FullUserData.graphql' from 'schemaValidation-test.js'"

如果我将 Fragments 文件夹移动到 __tests__ 目录中,则测试会很顺利。 关于我可以做些什么来欺骗评估以处理片段的任何想法,就好像我是相对于片段目录一样?

__tests__/
  - schemaValidation-test.js
queries/
  - someQuery.graphql
  - fragments/someFragment.graphql

我在 jest 中尝试了 process.chdir() 到查询目录,但没有骰子

这里是验证器:

// __tests__/schemaValidation-test.js
import glob from 'glob'
import { validate } from 'graphql/validation'
import loader from 'graphql-tag/loader'
import schema from 'api/lib/app/graphql/schema'
import path from 'path'
import fs from 'fs'

const gqlDir = path.join(__dirname, '..')

const queryDir = path.join(gqlDir, 'queries', 'shared')
const pattern = `${queryDir}/!(fragments)*.graphql`

const getGraphqlFiles = () => glob.sync(pattern)

describe('api schema', () => {
  const files = getGraphqlFiles()

  for(var file of files) {
    const buffer = fs.readFileSync(file)
    let document = (buffer || "").toString()

    try {
      document = eval(loader.call(
        { cacheable: () => ({}) },
        document
      ))
    } catch (e) {
      fail(`could not parse ${file}, ${e}`)
    }


    it(`${file} passes validation`, () => {
      const errors = validate(
        schema,
        document,
      )

      expect(errors).toEqual([])
    })
  }
})

如何告诉加载器我在相对于片段不同的目录中?

【问题讨论】:

  • FWIW, graphql-tag 明确声明它不应该用于测试。您应该改用jest-transform-graphql,如here 所述。
  • 值得一提的是上面的代码只会验证你的模式。如果您真的对识别重大更改感兴趣,您应该对架构进行快照,然后使用核心库中的 findBreakingChanges 实用程序。
  • 是的,这就是我的直接目标。我会看看你推荐的图书馆。丹尼尔,我也在用变压器。只是不适用于这个例子,我想支持自动发现添加到 repo 的 *.graphql 文件
  • 这个库不能满足我的需求,它看起来好像比较了 2 个模式。我只能访问 API 公开的单一模式。
  • 另外,在这种情况下,我正在积极使用 graphql-tag 来支持片段。除非您知道另一种加载 graphql 扩展和相关片段的方法

标签: node.js graphql jestjs


【解决方案1】:

我想通了。关键是使用require 而不是fs.readFileSync

import glob from 'glob'
import { validate } from 'graphql/validation'
import schema from 'api/lib/app/graphql/schema'
import path from 'path'

const gqlDir = path.join(__dirname, '..')
const queryDir = path.join(gqlDir, 'queries', 'shared')
const pattern = `${queryDir}/!(fragments)*.graphql`

const getGraphqlFiles = () => glob.sync(pattern)

describe('rent-js-api schema', () => {
  const files = getGraphqlFiles()
  files.forEach(file => {
    /* eslint-disable import/no-dynamic-require */
    const document = require(file)

    it(`${file} passes validation`, () => {
      const errors = validate(
        schema,
        document,
      )

      expect(errors).toEqual([])
    })
  })
})

这里是 jest.config.json

{
  "setupFiles": [
    "<rootDir>/test/jest/shim.js",
    "<rootDir>/test/jest/setup.js"
  ],
  "moduleDirectories": ["node_modules", "src", "test/jest", "test"],
  "collectCoverage": false,
  "testMatch": ["**/*-test.js"],
  "collectCoverageFrom": [
    "**/src/**/*.{js,ts,jsx,tsx}",
    "!**/src/**/*-test.js",
    "!**/index.{ts,js}",
    "!**/src/**/const.{ts,js}",
    "!**/ui/theme/**",
    "!**/src/**/*.d.{ts,tsx}",
    "!**/node_modules/**",
    "!**/src/ui/*/themes/**"
  ],
  "coverageDirectory": "./coverage",
  "moduleNameMapper": {
    "\\.(css|scss)$": "<rootDir>/test/jest/noop-styles",
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/jest/noop-binary",
    "^.+\\.html$": "<rootDir>/test/jest/htmlLoader"
  },
  "moduleFileExtensions": [
    "graphql",
    "js",
    "json",
    "ts",
    "tsx"
  ],
  "transform": {
    "^.+\\.jsx?$": "babel-jest",
    "^.+\\.tsx?$": "babel-jest",
    "^.+\\.graphql$": "jest-transform-graphql"
  },
  "testPathIgnorePatterns": [
    "<rootDir>/node_modules/",
    "^.*__tests__/__helpers__.*"
  ],
  "snapshotSerializers": [
    "enzyme-to-json/serializer",
    "jest-serializer-html"
  ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2021-09-01
    • 2020-07-15
    • 2018-11-08
    • 2021-10-12
    • 2017-09-28
    • 1970-01-01
    相关资源
    最近更新 更多