My goal is to test the types of my GraphQL schema in ruby, I'm using the graphql-ruby gem.
I couldn't find any best practice for this, so I'm wondering what's the best way to test the fields and types of a Schema.
The gem recommends against testing the Schema directly http://graphql-ruby.org/schema/testing.html but I still find valuable to be able to know when the schema changes unexpectedly.
Having a type like this:
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
My first approach has been to use the fields
hash in the GraphQL::Schema::Object type, for example:
Types::DeskType.fields['location'].type.to_s => 'String!'
Creating an RSpec matcher, I could come up with tests that look like this:
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
This approach has some drawbacks though:
It looks you want to test your schema because you want to know if it is going to break the client. Basically you should avoid this.
Instead you can use gems like: graphql-schema_comparator
to print breaking changes.
What I feel is an improvement over the first approach I took is to use snapshot testing for the GraphQL Schema, instead of testing each of the types/mutation schemas one by one, I created a single test:
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
This approach uses a slightly modified version of the rspec-snapshot gem, see my PR here.
The gem doesn't let you update the snapshot with a single command like in Jest, so I also created a rake task to delete the current snapshot:
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
With this you'll get a pretty RSpec diff when the schema has been modified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With