GraphQLのNewRelicTracingがテスト時のみエラーになる。

TL;DR

テストでのみ、NameError: uninitialized constant GraphQL::Tracing::NewRelicTracing::NewRelicとエラーが出た。

原因は、gem 'newrelic_rpm'をテスト環境で導入していなかった。

テスト環境で導入するか、Rails.env.test? でテスト時はuse(GraphQL::Tracing::NewRelicTracing) を含めないようにする。

詳細

GraphQLで生じるN+1問題を解決するために、Gemの導入を検討する必要がありました。

まずは、現時点でのGraphQLのアクセスをNewRelicで監視対象に追加したかったので、GraphQL - Tracingを見て調べてました。

すると、GraphQL::Tracingを継承して自作の監視機能を作る方法が紹介されていました。

よくドキュメントを見ると、NewRelicはGraphQL-rubyでサポートされていることがわかりました。

早速、ドキュメント通りスキーマに定義しました。

class MySchema < GraphQL::Schema
  ~~~
  query(Types::QueryType)
  use(GraphQL::Tracing::NewRelicTracing, set_transaction_name: true)
  ~~~
end

CircleCIが落ちているので、ローカルで再現するとGraphQL全テストにて NameError: uninitialized constant GraphQL::Tracing::NewRelicTracing::NewRelic というエラーメッセージが表示されました。

GraphQL - Tracingのドキュメントはシンプルで目ぼしい解決はありませんでした。グーグル先生もGraphQLの知見は、まだ溜まってないようです。

仕方ないので、初めてソースコードを読むことになりました。RefineryCMSというGemを覗いたことはあったのですが、Railsの使い方をために読んだのでRubyによったものは、未経験でした。

より詳細なAPI-Docには、ソースコードの位置情報も載っています。

とりあえず、それっぽいファイルがありました。

graphql-ruby/tracing.rb at master · rmosolgo/graphql-ruby · GitHub

graphql-ruby/platform_tracing.rb at master · rmosolgo/graphql-ruby · GitHub

graphql-ruby/new_relic_tracing.rb at master · rmosolgo/graphql-ruby · GitHub

PlatformTracingが親となって、各プラットフォームが定義されていることがわかりました。

さて、問題はGraphQL::Tracing::NewRelicTracingにNewRelicというClassがあるとかです。ソースコードを見るとありませんね。

ここで、かなり時間を使ってしまったのでメンターの方に質問するとテストだけ呼び出すことができないかを確認した方がよいというアドバイスをもらいました。

そこで、development環境でクエリを叩くとエラーは出ませんでした。

少し悩んだ後、そもそも外部依存のNewRelicがテスト環境で使えないのではないかと思い、Gemfileを探すとgem 'newrelic_rpm' がテスト環境にありませんでした。

追加して、bundle installするとテストが通りました。

デバックの低さが目立ちかなりの時間を使ってしまいましたが、use がRack関連であることやソースコードを読むことで自前のTraceも実装できそうという自信がついたのでよかったです。

ご静聴ありがとうございました。