Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using dataloader on a mutation with rspec-mocks + lazy-evaluated mocked method causes code to hang #4172

Closed
khamusa opened this issue Aug 26, 2022 · 3 comments

Comments

@khamusa
Copy link
Contributor

khamusa commented Aug 26, 2022

Once again, thanks for this amazing gem. I'm pretty excited about experimenting with the dataloader for the first time. I've used lazy execution in the past to deal with n+1s in a Rails app, and the dataloader API feels pretty neat!

Describe the bug

Consider a doSomething mutation, plugged into a schema with the dataloader enabled, and a resolver such as this one:

  def resolve
    DoerOfSomething.do_something

    { done: true }
  end

And the following rspec test scenario:

subject(:mutation) do
  TestSchema.execute(query, variables: {}, context: {})
end

let(:query) do
  <<~GQL
    mutation DoSomething {
      doSomething(input: {}) {
        done
      }
    }
  GQL
end

before do
  allow(DoerOfSomething).to receive(:do_something) do
    puts 'Evaluating mocked_return_value using block_syntax'
    result = mocked_return_value #     <- the test hangs when the resolver calls DoerOfSomething.do_something and we reach this line
    puts 'Finished evaluating the let statement for the mocked return value'

    result
  end

  # If I use `.and_return(mocked_return_value)` it does not hang.
  # If I use `let!` (eager version) when defining `mocked_return_value`, it does not hang
  # If I force rspec to evaluate `mocked_return_value` before the mutation runs, it does not hang (which is what happened when using `.and_return`
end

it 'should run and complete' do
  subject

  expect(true).to be_truthy

  puts "Test finished"
end

The statements 'Finished evaluating the let statement for the mocked return value' and "Test finished" never get printed, and the test hangs forever.

The test is hanging when the lazy let statement is evaluated.

Versions

graphql version: 2.0.13 (but the bug was first identified on 1.12.5)
rails (or other framework): 7.0.3.1
other applicable versions (graphql-batch, etc)
rspec-rails (5.1.2)
rspec-core (3.11.0)
rspec-expectations (3.11.0)
rspec-mocks (3.11.1)

GraphQL schema

Please see this PR offering a minimal example.

Steps to reproduce

The easiest way is to use the repo I've created and run the tests:

git clone git@github.com:khamusa/gql-dataloader-rspec-mocks-hanging.git
cd gql-dataloader-rspec-mocks-hanging
git checkout bug-demo
bundle
bundle exec rspec

The failing test is on the bug-demo branch. You can see the diff on this PR if you'd rather not clone and run the repo directly (you'll need graphql and rspec-rails gems - or rspec directly, as I don't see how rails itself could be related). I've left some comments there stating what I have found so far (not much, sorry :( )

I came across this issue when working with mutations, but, in principle, it should affect queries as well.

Expected behavior

The lazily-defined let statement can be resolved successfully when dataloader is enabled, just like it is when dataloader is not plugged into the schema.

Actual behavior

The code hangs when trying to evaluate the mocked method that would return a lazy-evaluated let statement.

@khamusa khamusa changed the title Using dataloader with rspec-mocks causing code to hang when mocking methods with lazy-evaluated mocked result Using dataloader on a mutation with rspec-mocks + lazy-evaluated mocked method causes code to hang Aug 26, 2022
@rmosolgo
Copy link
Owner

Thanks for this great report and reproduction of the issue. I'll take a look soon and see if I can get to the bottom of it!

@rmosolgo
Copy link
Owner

I cloned your replication repo and inspected the stuck process, I think it might be an issue in Rspec, so I opened rspec/rspec-support#552. I'll keep an eye on that in the meantime.

@rmosolgo
Copy link
Owner

Sorry, I don't think there's anything else I can do on this right now, so I'm going to close it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants