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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

Q&A

解決済

1回答

1396閲覧

テストでassert_differenceがうまく動作しない

takuma1229

総合スコア11

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

0グッド

0クリップ

投稿2021/06/10 00:54

編集2021/06/10 00:55

前提・実現したいこと

RailsでWebアプリケーションを作っています。
テストのassert_differenceで以下のようなfailureが出ます。

FAIL["test_valid_signup/detail_information", #<Minitest::Reporters::Suite:0x000055e9bf3e1148 @name="UsersSignupTest">, 9.778686894999964] test_valid_signup/detail_information#UsersSignupTest (9.78s) "Detail.count" didn't change by 1. Expected: 3 Actual: 2 test/integration/users_signup_test.rb:34:in `block in <class:UsersSignupTest>'

countの値が増えていないというfailだと思います。
しかし、rails sを使ってブラウザ上で同じような動作をすると、問題なくsaveが行われ、Detailモデルに新しいデータが追加されます。

ソースコードを下述いたします。
なぜテスト上でDetail.countの値が増えないのかを教えていただきたいです。

程度の低い質問でしたら申し訳ございません。
また、質問に必要な情報等に不足があれば、お手数ですがご指摘いただければ、追記いたします。

よろしくお願いいたします。

該当のソースコード

ruby

1[user_signup_test.rb] 2require 'test_helper' 3 4class UsersSignupTest < ActionDispatch::IntegrationTest 5 6 test "invalid signup information" do 7 get signup_path 8 assert_no_difference "User.count" do 9 post users_path, params: { user: {name: "", 10 email: "user@invalid", 11 password: "foo", 12 password_confirmation: "bar" 13 } 14 15 } 16 end 17 assert_template 'users/new' 18 assert_select "div#error_explanation" 19 assert_select "div.alert" 20 end 21 22 test "valid signup/detail information" do 23 get signup_path 24 assert_difference "User.count", 1 do 25 post users_path, params: {user: {name: "Example.user", 26 email: "user@example.com", 27 password: "password", 28 password_confirmation: "password" 29 }} 30 end 31 follow_redirect! 32 assert_template 'users/details' 33 assert_not flash.empty? 34 assert is_logged_in? 35 assert_difference "Detail.count",1 do 36 post details_path,params: {detail: {user_id: User.find_by(name: 'Example.user').id, authenticity_token: "dajfisjfjs", mother_tongue: "Japanese", 37 japanese_level: "Beginner | 初心者", english_level: "Beginner | 初心者", 38 region: "Asia | アジア", purpose: "Business | 仕事", 39 self_introduction: "djifjiajfja", gender: "he/him | 男性", 40 sns_1: "djfiasf", sns_2: "jdifdjas", sns_3: "fadiofaj"}} 41 end 42 follow_redirect! 43 assert_template "users/show" 44 end 45 46 47end 48

ruby

1[users_controller.rb] 2class UsersController < ApplicationController 3 4 def show 5 @user = User.find(params[:id]) 6 end 7 8 def new 9 @user = User.new 10 end 11 12 def create 13 @user = User.new(user_params) 14 if @user.save 15 log_in @user 16 flash[:success] = "Welcome to INTE! Your account has been creaeted." 17 redirect_to details_path 18 else 19 flash[:danger] = "Invalid user information. Confirm that you filled all boxes except optional." 20 render 'new' 21 end 22 end 23 24 def details 25 end 26 27 def details_create 28 @detail = Detail.new(detail_params) 29 if @detail.save 30 redirect_to "/users/#{current_user.id}" 31 else 32 render 'details' 33 end 34 end 35 36 37 private 38 39 def user_params 40 params.require(:user).permit(:name, :email, :image, :password, :password_confirmation) 41 end 42 43 def detail_params 44 params.permit(:authenticity_token, :user_id, :mother_tongue, :japanese_level, :english_level, 45 :gender, :region, :purpose, :self_introduction, :sns_1, :sns_2, :sns_3) 46 end 47 48end 49

ruby

1[routes.rb] 2Rails.application.routes.draw do 3 4 get 'sessions/new' 5 root 'static_pages#language' 6 get '/home_jp', to:'static_pages#home_jp' 7 get '/home_en', to:'static_pages#home_en' 8 get '/signup', to:'users#new' 9 get '/details', to:'users#details' 10 post '/details', to:'users#details_create' 11 get '/login', to:'sessions#new' 12 post '/login', to:'sessions#create' 13 delete '/logout', to:'sessions#destroy' 14 # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 15 resources :users 16end 17

ruby

1[detail.rb] 2class Detail < ApplicationRecord 3 belongs_to :user 4 validates :mother_tongue, presence: true 5 validates :japanese_level, presence: true 6 validates :english_level, presence: true 7 validates :region, presence: true 8 validates :purpose, presence: true 9 validates :self_introduction, presence: true, length: {maximum:300} 10end 11

補足情報(FW/ツールのバージョンなど)

Rails 6.0.3
Ruby 2.6.3
AWS Cloud9を使用

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

def detail_params params.permit(:authenticity_token, :user_id, :mother_tongue, :japanese_level, :english_level, :gender, :region, :purpose, :self_introduction, :sns_1, :sns_2, :sns_3) end

post details_path,params: {detail: {...

見比べると、require(:detail)が必要か、{detail:が不要という事がわかるかなと思います。
view見ないとどちらが正しいのかわかりませんが

投稿2021/06/10 01:11

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takuma1229

2021/06/10 06:27

回答ありがとうございます。 {detail: を消してみたら成功しました! 本当にありがとうございます!   また、なぜこの方法でうまくいったのかを自分で考えてみたのですが、分かりかねました。 図々しくて恐縮なのですが、よろしければなぜ{detail: が不要だったのか教えてください。 自分としては上の"User.count"のassert_differenceの書き方を真似したのですが...
asm

2021/06/10 06:36

user_paramsがparams.require(:user).permit(...) detail_paramsがparams.permit(...)だからです。 この違いにより、paramsに期待している構造が変わります。
takuma1229

2021/06/10 06:39

なるほど! では、user_paramsがparams.permit(...)だった場合は、"User.count"のテストでも{user: は不要ということですね! 丁寧に教えてくださり、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問