今回詰まった内容を備忘録のためと、知識定着させるためアウトプット!
現在ポートフォリオで簡単な画像付きの投稿サイトを作成中、コントローラーの単体テストを行っておりました。
indexアクションにリクエストするとレスポンスに投稿済みの画像が存在する
上記テストだけがどうしてもうまくいかず、進まなかった状況です。
開発フレームワークはrails
を使用しており、
RSpec
FactoryBot
は導入済みの状態です。
エラー内容
TypeError:
no implicit conversion of ActiveStorage::Attached::Many into String
# ./spec/requests/posts_spec.rb:19:in `block (3 levels) in <top (required)>'
ソースコード
posts_spec.rb
equire 'rails_helper'
describe PostsController, type: :request do
before do
@post = FactoryBot.create(:post)
end
describe 'GET #index' do
it 'indexアクションにリクエストすると正常にレスポンスが返ってくる' do
get posts_path
expect(response.status).to eq 200
end
it 'indexアクションにリクエストするとレスポンスに投稿済みのテキストが存在する' do
get posts_path
expect(response.body).to include(@post.name)
end
it 'indexアクションにリクエストするとレスポンスに投稿済みの画像が存在する' do
get posts_path
expect(response.body).to include("@post.images")
end
it 'indexアクションにリクエストするとレスポンスに投稿検索フォームが存在する' do
get posts_path
expect(response.body).to include('')
end
end
end
posts.rb
FactoryBot.define do
factory :post do
name { '投稿名' }
post_text { '投稿文' }
association :user
after(:build) do |post|
post.images.attach(io: File.open('public/test_image.png'), filename: 'test_image.png')
end
end
end
上記の記述で行っていました。
どうしても画像の確認だけができず、つまずいていたという状況でした。
エラーログから考察するに、画像がstring(文字列型)になっているため確認が取れないよと認識する。
そのためbinding.pry
を入力してターミナル上で情報の確認
response.body
@post
@post.images
@post.images.blobs
上記全てをターミナル上で確認して、正常に画像がある事を把握する。
画像があるのに対して、string(文字列)になってしまっているエラーのためなぜかを考察する。
そこで、
include("@post.images")
上記の記述の仕方が行けないのではないかと仮説を立てる。
画像情報を取得しているname属性の値を入れてみた。
include("post[images][]")
上記に変更してみたが、同様のstring(文字列)のエラーが出ている。
それでエラーが出るのであれば、直接画像のimg属性のクラス名を指定するやり方で再度実行する
include("item-box-img")
上記コードで出力を行う。
そうしたらテストが成功した。
エラーの原因で文字列になってしまっているというところに着目し、修正を加えて行ったのがエラー解読につながったとみている。
未だ一点だけ不明点があり、
なぜ画像を指定する際に、その画像のname属性ではなく、クラスを指定しなくては行けないのかという点が不明であった。
同じ指定方法をしているのになぜなんだろうと思っている。
参考記事等も見つからず、もしご教授いただけるようでしたら、コメントいただけましたら助かります!
今回はコントローラー単体テストで画像確認のテストをする際におきたエラーでした。
同じようなエラーで迷われている方いましたら、是非ご参考にして頂けましたら幸いです!
宜しくお願いします!