anna
anna

Reputation: 85

How to mock a GraphQL type in Rails engine rspec?

I'm working inside a Rails engine where I have a GraphQL type.

module RailsEngine
  module Graph
    module RailsEngine
      module Types
        MyClass = GraphQL::ObjectType.define do
          # some working code here

          field :user, RailsEngine.graph_user_type.constantize, 'The description of user'
        end
      end
    end
  end
end

graph_user_type is a method that I define in the mattr_accessor and am getting a specific class of User from the main Rails app through the initializer.

When I'm running my Rspec tests for this type, I'm getting an error NameError: uninitialized constant Graph

So I was thinking of mocking the whole line field :user, RailsEngine.graph_user_type.constantize, 'The description of user' like this:

  before do
    user_type = double('Graph::User::Types::User')
    allow(described_class.fields['user']).to receive(:constantize).and_return(user_type)
  end

I've also tried allow(described_class.fields['user']).to receive(:type).and_return(user_type) also to no avail!

But I'm still getting the same error! Any ideas?

Failure/Error: field :user, RailsEngine.graph_user_type.constantize, 'The description of user'

NameError:
  uninitialized constant Graph```


Upvotes: 0

Views: 1226

Answers (2)

anna
anna

Reputation: 85

So the issue was hidden here

graph_user_type is a method that I define in the mattr_accessor and am getting a specific class of User from the main Rails app through the initializer.

Since I was getting the method graph_user_type through the initializer to the engine from the main app, before the spec was loaded, the error was already thrown - so it was useless to mock it inside the spec.

The solution was to add the very same thing that the main app initializer had to the dummy initializer inside the engine (with an indication that the data is mocked)

This was my initializer: RailsEngine.graph_user_type = 'Graph::User::Types::User'

This was my dummy initializer inside Engine: RailsEngine.graph_user_type = 'MockUserType'

Upvotes: 0

Greg
Greg

Reputation: 6648

before do
  user_type = double('Graph::User::Types::User')
  allow(described_class.fields['user']).to receive(:constantize).and_return(user_type)
end

You need to understand what allow method does. It takes an object, on which later expectation is set with .to receive(...).

What seems to have more sense, would be:

allow(RailsEngine).to receive(:graph_user_type).and_return('Graph::User::Types::User')

or, if you need it to return a double, you'd do sth like

allow(RailsEngine).to receive_message_chain('graph_user_type.constantize').and_return(user_type)

https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/message-chains

This way you're controlling what RailsEngine.graph_user_type is returning, and being passed on field as a second argument.

Upvotes: 1

Related Questions