エラーの内容
Railsで開発中のアプリケーションのテストをRSpecで行っていたところ、急にテストが失敗するようになった。
ただし、結果を確認すると前半のテストは成功しており、後半のテストが全て失敗している。
そして、失敗した4つのテストのうち、エラー文は以下のとおり表示されていた。
① Mysql2::Error::ConnectionError: Lost connection to MySQL server during query
② Mysql2::Error: MySQL client is not connected
③ Mysql2::Error: MySQL client is not connected
④ Mysql2::Error: MySQL client is not connected
エラー文の考察
1つ目のエラー文の内容は、**「クエリ(命令のこと。ここではテスト実行のこと。)の実行中にMySQLサーバーとの接続が失われた」**ということなので、2つ目以降のエラーは全てMySQLとの接続がないのでエラーになっていると考えられる。
原因
ググったところ、テスト用インスタンスを生成する際に複数のインスタンスを生成する記述をしていると、テストの実行中に何らかの負荷が生じ、テストが失敗することがあるみたい。
今回の場合は、クエリを実行してから処理が終わるまでの間に、すべてのテストを実行できずに結果が返ってきてしまったという感じでしょうか。
解決策
以下の一文をテストファイルに記述したら無事にテストが通りました。
require 'rails_helper'
RSpec.describe OrderShipping, type: :model do
before do
# 自分で関連付けを定義するためにuserインスタンスとitemインスタンスを生成
user = FactoryBot.create(:user)
item = FactoryBot.create(:item)
# 関連付けを定義しながら@order_shippingを生成
@order_shipping = FactoryBot.build(:order_shipping, user_id: user.id, item_id: item.id)
# この一文を追加
sleep 0.1
end
sleepメソッドは、一定時間、rubyプログラムの実行をストップするメソッドです。
一定時間経過後、次の行からプログラムが再度開始されます。
(この場所に記述したらテストが成功したということは、インスタンスをきちんと作り終えていなかったということ?)
最後に
正直に言って今回のエラーの原因は特定できていない。
ただ、今回テストしているモデルは実はフォームオブジェクトパターンを利用して作成したクラスに対するテストで、Railsのモデルとは若干異なる。
なのでFactoryBotでアソシエーションの記述ができず、単体テストファイル内で自分で関連するインスタンスを作っているのだが、これが関係あるのかな?
原因解明できたらこの記事を修正したいと思います!