Skip to content

Verify ruby-graphql responses with a :graphql spec type

License

Notifications You must be signed in to change notification settings

testdouble/rspec-graphql_response

Repository files navigation

Rspec::GraphQLResponse

RSpec::GraphQLResponse provides a series of RSpec matchers, helper methods, and other configuration to help simplify the testing of responses from the graphql-ruby gem and the <GraphQLSchemaName>.execute method.

"Why Should I Use This?"

There are a number of built-in helper methods and matchers that will allow you to skip the copy & paste work of executing a GraphQL Schema .execute. Additionally, there are custom matchers and other bits that will help simplify your work in validating common peices of a graphql response.

Lastly, the work in this gem is geared toward customization for your own application's needs. Every API call used for building the pieces of this gem are available to you, directly, in the API / Development documentation, below.

Installation

Your app must have graphql-ruby and rspec. With that done, add this line to your application's Gemfile:

gem 'rspec-graphql_response'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rspec-graphql_response

Full Documentation

The full documentation for RSpec::GraphQLResponse can be found in the /docs folder.

Configuration:

Custom Matchers:

  • have_errors - validates errors, or lack of, on the GraphQL response
  • have_field - validates the presence of a specified graphql operation in the graphql response

Context / Describe Helper Methods:

Spec Helper Methods:

  • execute_graphql - executes a graphql call with the registered schema, query, variables and context
  • response - the response, as JSON, of the executed graphql query
  • response_data - digs through the graphql response to return data from the specified node(s)

API / Development

  • .add_matcher - add a custom RSpec matcher to the GraphQLResponse matchers
  • .add_validator - add a custom validator to be used by the custom matchers
  • .add_helper - add helper methods to your specs, made avialable in it or describe / context blocks

Getting Started

There are only a couple of bits you need to get started:

RSpec::GraphQLResponse.configure do |config|
  config.graphql_schema = MyGraphQLSchema
end

RSpec.describe My::Cool::Thing, type: :graphql do
  # ...
end

Beyond these two basic needs, understanding the reason for this gem's existence can be useful in figuring out what the gem does, and what methods and options are available.

How We Got Here

Executing a GraphQL call from RSpec is not the most challenging code to write:

let(:query) do
  <<-GQL
    query ListCharacters{
      characters {
        id
        name
      }
    }
  GQL
end

subject do
  MySchema.execute(query)
end

it "does something" do
  response = subject.to_h

  # expect(response) ...
end

But copy & paste is often considered a design error, and this code is likely going to be littered throughout your spec files.

Use the Built-In execute_graphql

To help reduce the copy & paste, RSpec::GraphQLResponse has a built-in execute_graphql method that looks for a query variable in your specs.

RSpec.describe Some::Thing, type: :graphql do
  graphql_operation <<-GQL
    query ListCharacters{
      characters {
        id
        name
      }
    }
  GQL

  it "executes the query" do
    response = execute_graphql.to_h

    # expect(response) ...
  end
end

Use the Built-In response

The reduction in code is good, but the copy & paste of response = execute_graphql.to_h will quickly become an issue in the same way. The reduce this, RSpec::GraphQLResponse provides a built-in response helper.

RSpec.describe Some::Thing, type: :graphql do
  graphql_operation <<-GQL
    query ListCharacters{
      characters {
        id
        name
      }
    }
  GQL

  it "executes the query" do
    expect(response).to include(
      "data" => {
        "characters" => { ... }
      }
    )
  end
end

Retrieve response results with response_data

Now that the GraphQL query has been executed and a response has been obtained, it's time to check for the results of a GraphQL operation. In the previous example, the spec is expecting to find data with characters in the response hash. To reduce the nested hash checking, use the built-in response_data method to retrieve the characters:

RSpec.describe Some::Thing, type: :graphql do
  graphql_operation <<-GQL
    query ListCharacters{
      characters {
        id
        name
      }
    }
  GQL

  it "executes the query" do
    expect(response_data :characters).to include(
      # ...
    )
  end
end

Note the lack of response use here. Internally, the response_data method uses the response to obtain the data requested. This means the entire chain of operations from executing the GraphQL request, to converting the response into a hash, and digging through the results to find the correction operation, has been handled behind the scenes. To see more examples of how to use response_data dig through your response check out it's full documenation here.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/testdouble/rspec-graphql_response. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Rspec::GraphQLResponse project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.