ユーザー新規登録時の結合テストコードでやや苦戦したので紹介したいと思います。僕が苦戦したのはユーザー情報の入力です。アプリで結合テストコードを書くのは2回目だったので、初歩的な問題になります。
押さえるべきポイントは以下の2点です。
1. fill_inでname属性を指定できる
2. 選択の場合はselectを用いる
1. fill_inでname属性を指定できる
fill_inを用いるとユーザー情報を入力できます。僕が過去に結合テストコードを実行した際はfill_inでラベル名を指定していました。
app/views/devise/registrations/new.html.erb
<div class="field">
<%= f.label :nickname %> <em>(6 characters maximum)</em><br />
<%= f.text_field :nickname, autofocus: true %>
</div>
検証ツールを用いるとlabelのfor属性と入力欄のidが一致していたため、fill_inにラベル名を指定することでテストをうまく実行できていました。
fill_in 'Nickname', with: @user.nickname
この時はラベル名がニックネームでした。
しかし今回の実装ではこのように記述していたため、検証ツールを用いて調べてもfor属性はありませんでした。
<div class="form-group">
<div class='form-text-wrap'>
<label class="form-text">ニックネーム</label>
<span class="indispensable">必須</span>
</div>
<%= f.text_area :nickname, class:"input-default", id:"nickname",
placeholder:"例) furima太郎", maxlength:"40" %>
</div>
試しにこのような記述をしてみてもうまく行きませんでした。
fill_in 'ニックネーム', with: @user.nickname
そこでラベル名以外を指定してみようと考えて、入力欄のname属性を指定するとうまく行きました。
fill_in 'user[nickname]', with: @user.nickname
name属性を指定することでemailやpasswordなどもうまく行きました。
2. 選択の場合はselectを用いる
ところが生年月日のところでつまづいてしまいました。生年月日はこのように記述していました。カラム名はbirth_dateという1つだけなのですが、実際に入力する値は年と月と日で3箇所あります。
<div class='input-birth-wrap'>
<%= raw sprintf(
f.date_select(
:birth_date,
class:'select-birth',
id:"birth-date",
use_month_numbers: true,
prompt:'--',
start_year: 1930,
end_year: (Time.now.year - 5),
date_separator: '%s'),
"<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>
</div>
このような記述をしてもうまくいくはずがありません。
fill_in 'user[birth_date(1i)]', with: @user.birth_date
fill_in 'user[birth_date(2i)]', with: @user.birth_date
fill_in 'user[birth_date(3i)]', with: @user.birth_date
FactoryBotで値を生成して使ってみようと試みましたが、そもそもそんなカラム名を作っていません。
birth_date_1i { Faker::Number.between(from: 2, to: 88) }
birth_date_2i { Faker::Number.between(from: 2, to: 13) }
birth_date_3i { Faker::Number.between(from: 2, to: 32) }
自分で値を決めて入力してみてもうまく行きません。
fill_in 'user[birth_date(1i)]', with: 1960
fill_in 'user[birth_date(2i)]', with: 10
fill_in 'user[birth_date(3i)]', with: 10
その時に、「あ、そもそもfill_inを使うのが間違いなんだ」と気づき、以下のように修正するとうまく行きました。
select '1960',from: 'user[birth_date(1i)]'
select '10',from: 'user[birth_date(2i)]'
select '10',from: 'user[birth_date(3i)]'
これで後は問題なく新規登録時のテストはうまく作動しました。
このような初歩的なことに時間を使わないように気をつけましょう。