はじめに
テストコードを記述していると、シリアライズされたデータの検証に直面することがあります。私のケースでは、あるメソッドの戻り値がシリアライザーによって生成されたデータであり、通常のオブジェクトのように have_attributes を用いて簡単にテストできませんでした。
当初は、OpenStruct を使ってこれを解決しようとしましたが、OpenStruct は非推奨であることを知り、最終的に .object を利用する方法に切り替えました。本記事では、その経緯と理由について共有します。
課題:シリアライズされたデータの検証
以下のように、update の戻り値である output を検証したいと考えました。
require 'ostruct'
describe UserProfileUpdater do
describe '.update' do
let(:params) do
{
user_id: 1,
name: 'hashimoto',
email: 'duhfaiudfhai.com',
address: 'Tokyo'
}
end
it 'updates the profile successfully' do
response = described_class.update(params)
serialized_response = OpenStruct.new(response)
expect(serialized_response).to have_attributes(
name: params[:name],
email: params[:email],
address: params[:address]
)
end
end
end
課題
非推奨の使用:
OpenStruct はパフォーマンスや安全性の面から非推奨とされており、長期的な使用が推奨されません。
余計な変換:
レスポンスデータをわざわざ OpenStruct に変換する手間が増えます。
以上のような課題があった。
解決策: .objectを活用する
上記の課題に対して、.objectを活用することで、シリアライズされたデータを元のRubyオブジェクトとして扱う方法を採用しました。このアプローチは、不要な変換を省き、テストコードをシンプルかつ効率的に記述できます。
describe UserProfileUpdater do
describe '.update' do
let(:params) do
{
user_id: 1,
name: 'hashimoto',
email: 'duhfaiudfhai.com',
address: 'Tokyo'
}
end
it 'updates the profile successfully' do
response = described_class.update(params)
serialized_response = response.object # .objectで元のオブジェクトを取得
expect(serialized_response).to have_attributes(
name: params[:name],
email: params[:email],
address: params[:address]
)
end
end
end
上記の方法を採用することで、以下のようなメリットを得ることができました。
メンテナンス性の向上:
長期的なプロジェクトでも安心して使用できる方法を採用することで、将来的な変更や対応が容易になる。
開発効率の向上:
無駄な変換や非推奨な方法に悩まされることなく、テストコードの記述に集中できる。
まとめ
シリアライズされたデータのテストで課題に直面した際、.objectを活用することで、簡潔かつ効率的に問題を解決できました。今後、テストコードでシリアライズされたデータを検証する場合は、ぜひ.objectを活用しようと思います。
⚠️あくまで、個人的な解釈ですので参考程度にしていただけると幸いです。