はじめに
いよいよRspecに手を出すことにした。これを使ったらいろんなテストができるらしい。すごい。でも、ちょっと手強そうだったのでオンライン教材を使用することにした。こちらのTake off Railsというものだ。
最近は時間が足りないので、いろんな物事を効率化する必要があった。時間をお金で買う形だが、これが非常によかった。情報が集約されているし、分からなかったら質問した。
それでも結構詰まったことがあったので、ここに書いておく。
rails g model user -s ができない
今回は既存のuser modelに対してspec/models/user_spec.rb
やspec/factories/users.rb
を作成するため、
$ rails g model user -s
を実行しようとした。しかし、エラーが生じた。
$ rails g model user -s
Running via Spring preloader in process 1605
invoke active_record
The name 'User' is either already used in your application or reserved by Ruby on Rails.
Please choose an alternative or use --force to skip this check and run this generator again.
どうやらskipオプションが使えないらしかった。質問をして、変更後のファイルをすべてcommitしてから$ rails g model user --force
を行い $ git restore .
を実行した。こうすることで、skipと同じ効果が得られた。
deviseと普通のアクションのURLが被ってエラー
userコントローラーのcreateアクションについてテストを実施しようとしたら以下のようなエラーが出た。
Failures:
1) Users POST /users ユーザーのレコードが作成できる
Failure/Error: expect{subject }.to change { User.count }.by(1)
expected `User.count` to have changed by 1, but was changed by 0
# ./spec/requests/users_spec.rb:53:in `block (3 levels) in <main>'
原因を探っていくと、user#createアクションへ遷移していないことがわかった。その代わりdeviseの#createアクションが実行されていたのだった。
$rails routes
で確認するとdevise#controller とuser#controller のパスが同じものになっていた。ちょっとこれを変えてやらないといけない。
以下のように設定した。
Rails.application.routes.draw do
root to: 'users#index'
devise_for :users
resources :users ,path_names: { create: 'make' } do
resources :plants do
resources :growth_records, shallow: true
end
end
scope 'username' do
resources :users, only: [:create]
end
end
今回は scope
の箇所を変更した。これにより、ルーティングの衝突がなくなった。テストの一部は以下のようになっている。
RSpec.describe "Users", type: :request do
# 中略-----
describe "POST /users" do
subject { post('/username/users' ,params: params) }
let(:params){ {user: attributes_for(:user)} }
it "ユーザーのレコードが作成できる" do
expect{subject }.to change { User.count }.by(1)
expect(response).to have_http_status(204)
end
end
# 中略-----
end
以前の post(users_path,params: params)
からpost('/username/users' ,params: params)
に変更している。
おわり
Rspecの世界は奥が深い。いまはエラーが出ないことだけを意識しているが、いづれは自分で「何のテストがどこまで必要か」までを考えていきたい。
なんだかんだいって、プログラミングは楽しい。