簡體   English   中英

如何使用graphql-ruby測試GraphQL架構?

[英]How to test a GraphQL schema with graphql-ruby?

我的目標是在ruby中測試我的GraphQL模式的類型,我正在使用graphql-ruby gem。

我找不到任何最佳實踐,所以我想知道測試Schema的字段和類型的最佳方法是什么。

寶石建議不要直接測試Schema http://graphql-ruby.org/schema/testing.html但我仍然覺得有價值的是能夠知道架構何時意外更改。

有這樣的類型:

module Types
  class DeskType < GraphQL::Schema::Object
    field :id, ID, 'Id of this Desk', null: false
    field :location, String, 'Location of the Desk', null: false
    field :custom_id, String, 'Human-readable unique identifier for this desk', null: false
  end
end

我的第一種方法是使用GraphQL :: Schema :: Object類型中的fields哈希,例如:

Types::DeskType.fields['location'].type.to_s => 'String!'

創建RSpec匹配器,我可以得到如下所示的測試:

RSpec.describe Types::DeskType do
  it 'has the expected schema fields' do
    fields = {
      'id': 'ID!',
      'location': 'String!',
      'customId': 'String!'
    }

    expect(described_class).to match_schema_fields(fields)
  end
end

這種方法有一些缺點:

  • 匹配器中的代碼依賴於GraphQL :: Schema :: Object類的實現,任何重大更改都會在更新后破壞測試套件。
  • 我們重復代碼,測試斷言類型中的相同字段。
  • 編寫這些測試變得乏味,這使得開發人員不太可能編寫它們。

它看起來你想測試你的架構,因為你想知道它是否會破壞客戶端。 基本上你應該避免這種情況。

相反,你可以使用像: graphql-schema_comparator這樣的寶石來打印重大變化。

  1. 我建議有一個rake任務來轉儲你的模式(並在你的repo中提交它)。
  2. 您可以編寫一些規范來檢查架構是否轉儲 - 然后您將確保,您始終擁有最新的架構轉儲。
  3. 設置CI以將當前分支的模式與主分支上的模式進行比較。
  4. 如果架構有危險或破壞性更改,則無法構建。
  5. 您甚至可以使用模式比較器生成模式更改日志;)或者您甚至可以使用松弛通知來發送任何模式更改,以便您的團隊可以輕松跟蹤任何更改。

我覺得我對第一種方法的改進是對GraphQL Schema使用快照測試,而不是逐個測試每個類型/突變模式,我創建了一個測試:

RSpec.describe MySchema do
  it 'renders the full schema' do
    schema = GraphQL::Schema::Printer.print_schema(MySchema)
    expect(schema).to match_snapshot('schema')
  end
end

這種方法使用稍微修改過的rspec-snapshot gem版本, 請參閱我的PR

gem不允許您使用像Jest中的單個命令更新快照,因此我還創建了一個rake任務來刪除當前快照:

namespace :tests do
  desc 'Deletes the schema snapshot'

  task delete_schema_snapshot: :environment do
    snapshot_path = Rails.root.join('spec', 'fixtures', 'snapshots', 'schema.snap')
    File.delete(snapshot_path) if File.exist?(snapshot_path)
  end
end

有了這個,你可以在修改架構時獲得漂亮的RSpec差異。

頂級Schema對象具有#execute方法 您可以使用它來編寫類似的測試

RSpec.describe MySchema do
  it 'fetches an object' do
    id = 'Zm9vOjE'
    query = <<~GRAPHQL
      query GetObject($id: ID!) {
        node(id: $id) { __typename id }
      }
    GRAPHQL
    res = described_class.execute(
      query,
      variables: { id: id }
    )
    expect(res['errors']).to be_nil
    expect(res['data']['node']['__typename']).to eq('Foo')
    expect(res['data']['node']['id']).to eq(id)
  end
end

#execute方法的返回值將是傳統的HTTP樣式響應,作為字符串鍵控哈希。 (實際上它是一個GraphQL :: Query :: Result ,但它將大部分內容委托給嵌入式哈希。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM