3

My Rails 7, Ruby 3.1 App has a simple test that is failing. I am not understanding why.

In my App I have added a support directory labelled stuff, which has some GraphQL code in it. So in my tests, I want to do a GraphQL.test(foo: "me", bar: "you").

app/stuff/graphql.rb

In my inflections.rb initializer, I teach the Inflection I want.

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.acronym 'GraphQL'
end

In my application.rb, I tell Zeitwerk that I have stuff to work with, and the rake task zeitwerk:check says everything is good.

The graphql.rb has a simple test function:

module GraphQL
  def self.test(foo:, bar:)
    puts "We got a #{foo} and a #{bar}"
  end
end

But my tests run, and when testing out this code, the test fails on GraphQL not having a test method.

I am confused by the autoloading and eager loading, and why my tests seem unable to follow the simple setup here.

David Lazar
  • 10,865
  • 3
  • 25
  • 38
  • I can't reproduce this and its going to be hard to help you without an actual reproducable example. Make sure you have eliminated any workflow related issues like unsaved files, run `spring stop` and try again. – max Jan 10 '22 at 13:31
  • 1
    Its also very unclear what you mean by "In my application.rb, I tell Zeitwerk that I have stuff to work with". You should not have to do anything. Every subdirectory of `app` is automatically made into a autoloading/eagerloading root where Zeitwerk will look for top level constants. – max Jan 10 '22 at 13:33
  • I believe there is a namespace issue with Zeitwerk here. I try and use the Object GraphQL which indeed has an execute method attached to it, but Zeitwerk is coming up with a different GraphQL object in the tree. I was was if the config file application.rb. It is stripped bare, and so I am indeed letting Zeitwork try and do its thing without interference. – David Lazar Jan 10 '22 at 14:48
  • Ah, if you're using a gem for example that provides a `GraphQL` constant then it will be loaded by `Bundler.require(*Rails.groups)` in `application.rb`. Since the constant is already loaded Zeitwerk will not autoload your file. If you want to monkeypatch an existing constant the way to do it would be to define something like `GraphQL::MyMonkeypatch` and extend the `GraphQL` module with it in a an initializer. https://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/ – max Jan 10 '22 at 14:55

1 Answers1

1

It seems this was due to namespace issues with Zeitwerk. In my tests, I had a require that introduced the same namespace on a different object, namely GraphQL. So when in the tests, the named method was not found, as the Object returned was in the wrong namespacce. I removed the require, and the tests completed as expected, with no errors.

David Lazar
  • 10,865
  • 3
  • 25
  • 38