Jul 27, 2017

Testing graphql-ruby resolve classes with rspec

This is going to be a relatively short post. It’s something I just did and felt like sharing in the moment.

I have this project that uses graphql-ruby (it’s an amazing gem). As you quickly find out, it’s neater to have separate classes to DRY up commonly used resolver functionality.

An example of this is below, I have a lot of fields that need to be converted from kobo to Naira. I persist amounts of money in kobo while the front-end needs to display Naira to the user.

FooType = GraphQL::ObjectType.define do
  name 'Foo'
  description 'Foo Something'

  ...
  field :price, function: Resolvers::ToNaira.new
  ...
end

And the resolver class looks like this

module Resolvers
  class ToNaira < GraphQL::Function
    type Types::Scalar::BigDecimalType

    def call(obj, args, ctx)
      naira_amount = obj.send(ctx.field.name.underscore)
      naira_amount / 100
    end
  end
end

I use ctx.field.name to get the model attribute so I don’t have to pass any arguments into Resolvers::ToNaira.new

As expected, you’ll want to test these resolver classes’ call method.

So this is what I came up with.

 RSpec.describe Resolvers::ToNaira do
  subject(:result) do
    described_class.new.call(obj, args, ctx)
  end
  let(:ctx) {double('GraphQL::Query::Context', field: field)}
  let(:field) {double('GraphqQL::Field', name: field_name)}
  let(:obj) {create(:trade)}
  let(:args) {{}}
  let(:field_name) {'maximumAmount'}

  it 'returns the correct value' do
    expect(result).to eq(obj.maximum_amount/100)
  end
end 

And it works!

If anybody sees any way this can be better, feel free to let me know. I appreciate all feedback.

Copied to clipboard!