前提・実現したいこと
この質問で解決したいこと:Rspecでcreateメソッドで保存した値を用いてテストを実行したい
こちらでの質問は初めてのため、質問内容に至らぬ点が多々あるかもしれません。
大変お手数ですが、情報に不備がある場合はご指摘いただけますと幸いです。
開発内容:惣菜投稿サイト。会員情報を登録したユーザーが惣菜を投稿・共有することを目的としたサイト。
エラーが起きている内容:Rspecでの投稿機能のコントローラー単体テスト実装中に、createメソッドで値を保存してテストを実行したいが、データベースのエラーが出てしまう
最終目標:createメソッドで値を保存し、投稿機能のコントローラー単体テストを実行すること
発生している問題・エラーメッセージ
1) Delis Controller GET #index indexアクションにリクエストすると正常にレスポンスが返ってくる Failure/Error: @deli = FactoryBot.create(:deli) ActiveRecord::NotNullViolation: Mysql2::Error: Field 'name' doesn't have a default value # ./spec/requests/delis_spec.rb:5:in `block (2 levels) in <top (required)>' # ------------------ # --- Caused by: --- # Mysql2::Error: # Field 'name' doesn't have a default value # ./spec/requests/delis_spec.rb:5:in `block (2 levels) in <top (required)>'
該当のソースコード
delis_spec.rb
ruby
1require 'rails_helper' 2 3RSpec.describe "Delis Controller", type: :request do 4 before do 5 @deli = FactoryBot.create(:deli) 6 sleep(1) 7 end 8 9 describe "GET #index" do 10 it "indexアクションにリクエストすると正常にレスポンスが返ってくる" do 11 get root_path 12 expect(response.status).to eq(200) 13 end 14 15 it 'indexアクションにリクエストするとレスポンスに投稿済みの惣菜名が存在する' do 16 get root_path 17 expect(response.body).to include(@deli.name) 18 end 19 end 20end
delis.rb
ruby
1FactoryBot.define do 2 factory :deli do 3 name {Faker::Food.dish} 4 text {Faker::Lorem.sentence} 5 supermarket_id{rand(1..10)} 6 association :user 7 association :category 8 after(:build) do |deli| 9 deli.image.attach(io: File.open("#{Rails.root}/public/testimage.jpg"), filename:'testimage.jpg') 10 end 11 end 12end
deli.rb(モデルコントローラー記述内容)
ruby
1class Deli < ApplicationRecord 2 3 with_options presence:true do 4 validates :name 5 validates :text 6 validates :supermarket_id 7 validates :image 8 end 9 10 belongs_to :user 11 belongs_to :category 12 has_one_attached :image 13 extend ActiveHash::Associations::ActiveRecordExtensions 14 belongs_to_active_hash :supermarket 15end
delis_controkker.rb(コントローラー記述内容、new/createメソッドのみ記載しています。)
ruby
1class DelisController < ApplicationController 2 3〜前略〜 4 5 def index 6 @delis = Deli.all 7 end 8 9 def new 10 @deli = Deli.new 11 end 12 13 def create 14 @deli = Deli.new(deli_params) 15 if @deli.save 16 redirect_to root_path 17 else 18 render :new 19 end 20 end 21 22〜中略〜 23 24 private 25 def deli_params 26 params.require(:deli).permit(:name, :text, :category_id, :supermarket_id, :image).merge(user_id: current_user.id) 27 end 28end
マイグレーションファイル
ruby
1class CreateDelis < ActiveRecord::Migration[6.0] 2 def change 3 create_table :delis do |t| 4 5 t.string :name, null:false 6 t.text :text, null:false 7 t.integer :supermarket_id, null:false 8 t.references :user, null:false, foreign_key: true 9 t.references :category, null:false, foreign_key: true 10 t.timestamps 11 end 12 end 13end
試したこと
- エラー文からマイグレーションファイルやコントローラーのパラメーター部分に問題があると仮定し、記述内容を再確認
→確認後テスト結果に変化なし。尚、手動で新規投稿すると投稿が完了し、値が保存できている。
下記の記事を参照
https://qiita.com/divclass123/items/34c4a5a7200238a0589c
https://stackoverflow.com/questions/59644863/activerecordnotnullviolation-mysql2-column-cannot-be-null?answertab=active#tab-top
- テストコード内でbuildメソッド・saveメソッドと分けて記述を行う
→確認後のテスト結果に変化なし。なぜ二度手間の記述をしたかだが、buildメソッドでの値の生成のみは成功しているため、この方法を試した。
- FactoryBotによるnameカラムの値の生成を、Fakerを使用せず仮の文字列('test')で試みる
→確認後のテスト結果に変化なし。値の生成には問題なく、あくまで保存に関してデータベースの問題ではないかと考える
補足情報
ruby-version 2.6.5を使用。
長文で読みにくい文章になってしまい大変恐縮ですが、
ご助力いただけますと幸いです。
よろしくお願いいたします。
追記
値の生成についてテストファイル内に記述したところ、テストが成功しました。
そのことから、FactoryBotの記述に問題があるのでは?と考えております。
ruby
1require 'rails_helper' 2 3RSpec.describe "Delis", type: :request do 4 before do 5 @user = User.create(name:'sample', email:"aaa@yahoo.com", password:"sample00", password_confirmation:'sample00') 6 @deli = Deli.create(name:'test', text:'test', category_id:1, supermarket_id:1, user_id:1) 7 end 8 9 describe "GET /delis" do 10 it "indexアクションにリクエストすると正常にレスポンスが返ってくる" do 11 get root_path 12 expect(response.status).to eq(200) 13 end 14 15 it 'indexアクションにリクエストするとレスポンスに投稿済みの惣菜名が存在する' do 16 get root_path 17 expect(response.body).to include(@deli.name) 18 end 19 20 it 'indexアクションにリクエストするとレスポンスに投稿済みの画像が存在する' do 21 22 end 23 24 it 'indexアクションにリクエストするとレスポンスにカテゴリー名が存在する' do 25 get root_path 26 expect(response.body).to include(@deli.category.name) 27 end 28 29 it 'indexアクションにリクエストするとレスポンスに投稿者のユーザー名が存在する' do 30 get root_path 31 expect(response.body).to include(@deli.user.name) 32 end 33 end 34end
回答2件
あなたの回答
tips
プレビュー