質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.10%

spec実行時にActiveRecord::StatementInvalidとなる

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 84

sakanafuto

score 0

前提・実現したいこと

つい先程までは成功していたのですが突然rspecによるテストが実行できなくなりました。

Ruby: 2.6.5
Rails: 6.0.3.2 (5.2.4.2のときでも似たようなエラーが発生したためrails6の問題ではないとは思います)
mysql: 8.0.19

発生している問題・エラーメッセージ

Railsでアプリを作成中、bundle exec rspecを行ったところ

DEPRECATION WARNING: #fog_provider is deprecated and has no effect (called from block in <main> at /Users/futo/Portfolio/stelle_app/config/initializers/carrierwave.rb:7)

An error occurred while loading ./spec/models/like_spec.rb.
Failure/Error: validates :password, presence: true, length: { minimum: 6 }, on: create

ActiveRecord::StatementInvalid:
  Mysql2::Error: Table 'stelle_app_test.users' doesn't exist
# ./app/models/user.rb:45:in `<class:User>'
# ./app/models/user.rb:23:in `<main>'
# ./config/routes.rb:4:in `block in <main>'
# ./config/routes.rb:1:in `<main>'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:4:in `require'
# ./spec/rails_helper.rb:4:in `<top (required)>'
# ./spec/models/like_spec.rb:22:in `require'
# ./spec/models/like_spec.rb:22:in `<top (required)>'
# ------------------
# --- Caused by: ---
# Mysql2::Error:
#   Table 'stelle_app_test.users' doesn't exist
#   ./app/models/user.rb:45:in `<class:User>'

An error occurred while loading ./spec/models/post_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

FrozenError:
  can't modify frozen Array
# ./config/environment.rb:5:in `<main>'
# ./spec/rails_helper.rb:4:in `<main>'
# ./spec/models/post_spec.rb:24:in `<main>'
省略
An error occurred while loading ./spec/requests/users_request_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

FrozenError:
  can't modify frozen Array
# ./config/environment.rb:5:in `<main>'
# ./spec/rails_helper.rb:4:in `<main>'
# ./spec/requests/users_request_spec.rb:1:in `<main>'
No examples found.

Finished in 0.00003 seconds (files took 1.19 seconds to load)
0 examples, 0 failures, 9 errors occurred outside of examples

というエラーになってしまいました。stelle_appというアプリケーションなのですが、どうやらstelle_app_testに問題があるみたいです。

試したこと

まず、マイグレーションファイルファイルがおかしくないか確認。

❯ rails db:migrate:status

database: stelle_app_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200630041519  Devise create users
   up     20200630052243  Create prefectures
   up     20200630052413  Create posts
   up     20200630053527  Create likes
   up     20200630053907  Create relationships


問題はなさそうです。
次にdbをリセットしてみる。

❯ rails db:migrate:reset
Dropped database 'stelle_app_development'
Dropped database 'stelle_app_test'
Created database 'stelle_app_development'
Created database 'stelle_app_test'

省略

== 20200630053907 CreateRelationships: migrating ==============================
-- create_table(:relationships)
   -> 0.0529s
== 20200630053907 CreateRelationships: migrated (0.0530s) =====================

Model files unchanged.

最後のModel files unchanged.が気になりますがエラーも起こらずrails sをしてlocalhostに接続してみても問題なくアプリは動く。。。
テスト環境に問題がありそう。。。

❯ rails db:migrate RAILS_ENV=test
DEPRECATION WARNING: #fog_provider is deprecated and has no effect (called from block in <main> at /Users/futo/Portfolio/stelle_app/config/initializers/carrierwave.rb:7)
rails aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'stelle_app_test.users' doesn't exist
❯ rails db:migrate --trace
** Invoke db:migrate (first_time)
省略
** Invoke environment
** Execute annotate_models
Model files unchanged.
mysql> show databases;
+------------------------+
| Database               |
+------------------------+
| information_schema     |
| mysql                  |
| performance_schema     |
| stelle_app_development |
| stelle_app_test        |
| sys                    |
+------------------------+
6 rows in set (0.01 sec)
❯ rails db:create:all
Database 'stelle_app_development' already exists
Database 'stelle_app_test' already exists
Access denied for user 'stelle_app'@'localhost' (using password: NO)
Couldn't create 'stelle_app_production' database. Please check your configuration.
rails aborted!
Mysql2::Error::ConnectionError: Access denied for user 'stelle_app'@'localhost' (using password: NO)
bin/rails:4:in `<main>'
Tasks: TOP => db:create:all
(See full trace by running task with --trace)

色々試してみましたがそれらしい原因が見つかりませんでした。

該当のソースコード

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'


gem 'rails', '>= 5.2.4.2'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'turbolinks', '~> 5'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 5.0.0'
gem 'jbuilder', '~> 2.5'
gem 'bcrypt', '~> 3.1.7'
gem 'bootsnap', '>= 1.1.0', require: false


# ---以下追加---
gem 'font-awesome-rails'
gem 'bootstrap', '~> 4.3.1'
gem 'bootstrap-honoka-rails' , '~> 4.3.1'
gem 'jquery-rails'
gem 'devise'
gem 'rails-i18n'
gem 'devise-i18n'
gem 'devise-i18n-views'
gem 'faker'
gem 'carrierwave'
gem 'mini_magick', '4.8.0'
gem 'fog-aws'
gem 'dotenv-rails'
gem 'ransack'


group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]

  # ---以下追加---  
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'spring-commands-rspec'
end


group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'

  # ---以下追加--- 
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'annotate'
  gem 'bullet'
  gem 'rails-flog', require: 'flog'
end


group :test do
  gem 'capybara', '>= 2.15'
  gem 'webdrivers', '~> 3.0'

  # ---以下追加---  
  gem 'selenium-webdriver'
  gem 'rspec_junit_formatter'
end


# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# MySQL. Versions 5.1.10 and up are supported.
#
# Install the MySQL driver
#   gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'
#
# And be sure to use new-style password hashing:
#   https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock

development:
  <<: *default
  database: stelle_app_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: stelle_app_test

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
production:
  <<: *default
  database: stelle_app_production
  username: stelle_app
  password: <%= ENV['STELLE_APP_DATABASE_PASSWORD'] %>
./config/enviroment.rb

# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!  #該当部分
./spec/rails_helper.rb

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)  #該当部分
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
./spec/requests/users_request_spec

require 'rails_helper'  #該当部分

RSpec.describe "Users", type: :request do

  describe "GET /show" do
    it "returns http success" do
      get "/users/show"
      expect(response).to have_http_status(:success)
    end
  end

  describe "GET /index" do
    it "returns http success" do
      get "/users/index"
      expect(response).to have_http_status(:success)
    end
  end

  describe "GET /edit" do
    it "returns http success" do
      get "/users/edit"
      expect(response).to have_http_status(:success)
    end
  end
end

なにか情報がありましたらお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • winterboum

    2020/07/01 13:48

    FrozenError:   can't modify frozen Array
    とあるのに migration を見に行くのが理解できないです。
    1)これらのfileの該当部分を載せてください
    # ./config/environment.rb:5:in `<main>'
    # ./spec/rails_helper.rb:4:in `<main>'
    # ./spec/requests/users_request_spec.rb:1:in `<main>'

    2)動いていた時と動かなくなった時までの間に何をしたのか、を載せてください

    キャンセル

  • sakanafuto

    2020/07/01 15:03

    該当コードの追加をしました。

    specが動いていたのは初めて書いたapplication_helper.rbに対するタイトルメソッドに対してのテストのみであり、

    $ rspec spec/helpers/application_helper_rspec.rb

    で正常に動作していました。その後User, Post, Prefecture, Relationshipのモデルを追加して開発を進め、キリがついたところでrspecに手をつけたところ今回のエラーが発生しました。

    キャンセル

  • winterboum

    2020/07/01 15:09

    それらのfileはいじっていないみたいですね。
    エラーをみていると DBアクセス関係と一番最初の「Failure/Error: validates :password, presence: true, 」があるようです。
    DBアクセス関係もうちょっと覗いてみますが、「Failure/Error: validates :password, presence: true, 」について調べて置いてほしいことがあります。
    FactoryBot使ってますか? そこで問題が起きているとこういうエラーになることがあります。Userのbotでvalidatinに引っかかるようなのがないか見てください

    キャンセル

  • sakanafuto

    2020/07/01 15:39

    解決できました!!!!
    おっしゃるとおり、「./app/models/user.rb」のバリデーションを確認してみたところ
    validates :password, presence: true, length: { minimum: 6 }, on: create
    となっており、パスワードの要求を新規作成(create)からのみ受け付けるために記述していた「on: create」を削除したところテストが実行できました。。。

    本当にありがとうございます。ここで質問していなかったら永遠にdb周りを調べていたと思います。
    この度はありがとうござました。

    キャンセル

回答 1

check解決した方法

0

winterboumさんとのやり取りの通り、/app/models/○○.rbのバリデーションに問題がありました。
on: createを削除すると正常に動きました。この度はありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる