LoginSignup
0
0

More than 1 year has passed since last update.

【rails6】モデル単体テストエラー ActiveRecord::StatementInvalid: Mysql2::Error: MySQL client is not connected

Posted at

こんにちは!プログラミング初学者です!
今日はアプリケーションのモデル単体テストコードでのエラー解決について書いていきます

エラー内容

ActiveRecord::StatementInvalid: Mysql2::Error: MySQL client is not connected

エラー画面は以下の通りです

% bundle exec rspec spec/models/comment_spec.rb

Comment
  記事へのコメント機能
    コメントが投稿できるとき
      フォームに正しく入力すれば投稿できる
    コメントが投稿できないとき
      コメントが空欄では投稿できない (FAILED - 1)
      ユーザーid(user_id)が空では投稿できない (FAILED - 2)
      記事id(article_id)が空では投稿できない (FAILED - 3)

Failures:

  1) Comment 記事へのコメント機能 コメントが投稿できないとき コメントが空欄では投稿できない
     Failure/Error: _query(sql, @query_options.merge(options))

     ActiveRecord::StatementInvalid:
       Mysql2::Error::ConnectionError: Lost connection to MySQL server during query

     # 見にくくなるので省略 #

     #   Showing full backtrace because every line was filtered out.
     #   See docs for RSpec::Configuration#backtrace_exclusion_patterns and
     #   RSpec::Configuration#backtrace_inclusion_patterns for more information.
     # ------------------
     # --- Caused by: ---
     # Mysql2::Error::ConnectionError:
     #   Lost connection to MySQL server during query
     #   /Users/私の名前/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query'

調べていると、原因は下記2つに絞られる様です
・MySQL serverの停止、再起動が原因で今まで使っていた network socket が使えなくなった
・SQL が read_timeout 以内に実行が終わらなかった

参照元
https://abicky.net/2017/09/17/014241/
・・・ありがとうございます!!

私の実行ファイルは行数も少ないので、全てに binding.pry を仕込んでみようと思います

spec/models/comment_spec.rb
RSpec.describe Comment, type: :model do
  before do
    @user = FactoryBot.create(:user)
    @article = FactoryBot.create(:article)
    @comment_user = FactoryBot.create(:user)
    @comment = FactoryBot.build(:comment, user_id: @comment_user.id, article_id: @article.id)
  end

  describe '記事へのコメント機能' do
    context 'コメントが投稿できるとき' do
      it 'フォームに正しく入力すれば投稿できる' do
        expect(@comment).to be_valid
      end
    end

    context 'コメントが投稿できないとき' do
      it 'コメントが空欄では投稿できない' do
        @comment.comment = ''
        @comment.valid?
     binding.pry
        expect(@comment.errors.full_messages).to include('Commentを入力してください')
      end
      it 'ユーザーid(user_id)が空では投稿できない' do
        @comment.user_id = nil
        @comment.valid?
     binding.pry
        expect(@comment.errors.full_messages).to include('Userを入力してください')
      end
      it '記事id(article_id)が空では投稿できない' do
        @comment.article_id = nil
        @comment.valid?
     binding.pry
        expect(@comment.errors.full_messages).to include('Articleを入力してください')
      end
    end
  end
end
% bundle exec rspec spec/models/comment_spec.rb

Comment
  記事へのコメント機能
    コメントが投稿できるとき
      フォームに正しく入力すれば投稿できる
    コメントが投稿できないとき

From: /Users/私/projects/アプリ/spec/models/comment_spec.rb:22 :

    17: 
    18:     context 'コメントが投稿できないとき' do
    19:       it 'コメントが空欄では投稿できない' do
    20:         @comment.comment = ''
    21:         @comment.valid?
 => 22:         binding.pry
    23:         expect(@comment.errors.full_messages).to include('Commentを入力してください')
    24:       end
    25:       it 'ユーザーid(user_id)が空では投稿できない' do
    26:         @comment.user_id = nil
    27:         @comment.valid?

[1] pry(#<RSpec::ExampleGroups::Comment::Nested::Nested_2>)> exit
      コメントが空欄では投稿できない

From: /Users/私/projects/アプリ/spec/models/comment_spec.rb:28 :

    23:         expect(@comment.errors.full_messages).to include('Commentを入力してください')
    24:       end
    25:       it 'ユーザーid(user_id)が空では投稿できない' do
    26:         @comment.user_id = nil
    27:         @comment.valid?
 => 28:         binding.pry
    29:         expect(@comment.errors.full_messages).to include('Userを入力してください')
    30:       end
    31:       it '記事id(article_id)が空では投稿できない' do
    32:         @comment.article_id = nil
    33:         @comment.valid?

[1] pry(#<RSpec::ExampleGroups::Comment::Nested::Nested_2>)> exit
      ユーザーid(user_id)が空では投稿できない

From: /Users/私/projects/アプリ/spec/models/comment_spec.rb:34 :

    29:         expect(@comment.errors.full_messages).to include('Userを入力してください')
    30:       end
    31:       it '記事id(article_id)が空では投稿できない' do
    32:         @comment.article_id = nil
    33:         @comment.valid?
 => 34:         binding.pry
    35:         expect(@comment.errors.full_messages).to include('Articleを入力してください')
    36:       end
    37:     end
    38:   end
    39: end

[1] pry(#<RSpec::ExampleGroups::Comment::Nested::Nested_2>)> exit
      記事id(article_id)が空では投稿できない

Finished in 4.98 seconds (files took 1.31 seconds to load)
4 examples, 0 failures

問題なく通りました!
では、 binding.pry を削除して、
before do 内を書き換えてみます

spec/models/comment_spec.rb
RSpec.describe Comment, type: :model do
  before do
    @user = FactoryBot.create(:user)
    @article = FactoryBot.create(:article)
    @comment_user = FactoryBot.create(:user)
    @comment = FactoryBot.build(:comment, user_id: @comment_user.id, article_id: @article.id)
    sleep(0.1) # ここを追加
  end

  # 以下の文章は binding.pry のみを削除してください。それ以外は何も変更しません

では…いざターミナルで実行!! 

% bundle exec rspec spec/models/comment_spec.rb

Comment
  記事へのコメント機能
    コメントが投稿できるとき
      フォームに正しく入力すれば投稿できる
    コメントが投稿できないとき
      コメントが空欄では投稿できない
      ユーザーid(user_id)が空では投稿できない
      記事id(article_id)が空では投稿できない

Finished in 0.50371 seconds (files took 1.31 seconds to load)
4 examples, 0 failures

問題なく終了できました〜

この sleep(0.1)ですが、
引数に秒数を渡すことによって、その秒数分処理を停止することができます
ms(ミリ秒)の場合は上記の様に引数へ(0.1)や(0.01)と記載すればOKです。
今回は連続した処理で、「SQL が read_timeout 以内に間に合わなかった」と推測します

一つの処理が終わったら0.1秒休憩させて次の処理をさせる
そんなイメージを持っていれば良いのではないでしょうか??

みなさんも解決できましたか?
さてさて、私は先に進むとします:runner:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0