📃
サンプルコードで学ぶ!RSpecでCSV機能をテストする方法
こんにちは!
ラブグラフエンジニアのひろです。
今回は、CSVデータを使った機能を RSpec でどのようにテストするかについて解説します。
この記事では、以下の3つのテスト方法を具体例と共に紹介します:
- CSVファイルを読み込む方法
- ヒアドキュメントでデータを直接利用する方法
- テンポラリファイル(
Tempfile
)を使う方法
CSV機能をテストする3つの手法
1. CSVファイルを読み込む方法
概要
テスト用のCSVファイルを spec/fixtures
ディレクトリなどに保存しておき、それを読み込んでテストする方法です。
実際の運用に近い形で検証できるため、複雑な構造や大規模データのテストに向いています。
サンプルコード
require "rails_helper"
RSpec.describe BatchOrderCreationFromCsvJob, type: :job do
describe "#perform" do
it "CSVファイルを読み込んで注文データを作成する" do
# 保存済みのCSVファイルパスを指定
csv_file_path = Rails.root.join("spec/fixtures/orders.csv")
# ジョブを実行
expect {
BatchOrderCreationFromCsvJob.perform_now(csv_file_path)
}.to change(Order, :count).by(2)
order1 = Order.find_by(product_name: "Pen")
order2 = Order.find_by(product_name: "Notebook")
expect(order1.quantity).to eq(10)
expect(order2.quantity).to eq(5)
end
end
end
準備するCSVファイル
以下の内容を spec/fixtures/orders.csv
に保存しておきます:
product_name,quantity
Pen,10
Notebook,5
メリット
- 実運用に近い形でテスト可能。
- 大規模データや複雑なCSV構造に対応しやすい。
デメリット
- 外部ファイルの管理が必要になる。
- ファイルが変更された場合、テストの再現性に影響を与える。
2. ヒアドキュメントでデータを直接利用する方法
概要
テストコード内にCSVデータを直接埋め込み、ファイルに保存せずにそのまま処理する方法です。
データがシンプルな場合や、小規模なロジックを検証したい場合に適しています。
サンプルコード
require "rails_helper"
RSpec.describe BatchOrderCreationFromCsvJob, type: :job do
describe "#perform" do
subject { described_class.new.perform(csv_content) }
let(:csv_content) do
<<~CSV
product_name,quantity
Pen,10
Notebook,5
CSV
end
it "CSVデータを直接利用して注文データを作成する" do
# ジョブを実行
subject
# 作成されたOrderの検証
expect(Order.count).to eq(2)
expect(Order.find_by(product_name: "Pen").quantity).to eq(10)
expect(Order.find_by(product_name: "Notebook").quantity).to eq(5)
end
end
end
メリット
- ファイル操作を省略でき、テストコードが簡潔。
- テスト内で完結するため、外部ファイル管理が不要。
デメリット
- CSVデータの中身を丸ごと受け取って処理するようなものしかテストできない。
- データが複雑になる場合や大量データには不向き。
- 実際のファイル入出力処理は検証できない。
Tempfile
)を使う方法
3. テンポラリファイル( 概要
一時的なファイルを生成し、そのファイルにデータを書き込んで利用するテスト。
ファイルの入出力処理を伴う場合や、テスト終了後にファイルを自動で削除したい場合に適しています。
サンプルコード
require "rails_helper"
RSpec.describe BatchOrderCreationFromCsvJob, type: :job do
describe "#perform" do
it "テンポラリファイルを利用して注文データを作成する" do
Tempfile.open(["orders", ".csv"]) do |tempfile|
tempfile.write("product_name,quantity\nPen,10\nNotebook,5\n")
tempfile.rewind
expect {
BatchOrderCreationFromCsvJob.perform_now(tempfile.path)
}.to change(Order, :count).by(2)
order1 = Order.find_by(product_name: "Pen")
order2 = Order.find_by(product_name: "Notebook")
expect(order1.quantity).to eq(10)
expect(order2.quantity).to eq(5)
end
end
end
end
メリット
- ファイル入出力処理の動作を検証可能。
- テスト終了後にファイルが自動的に削除されるため、管理が簡単。
デメリット
- データが複雑になる場合や大量データには不向き。
各手法の使い分けガイド
紹介した3つの手法を使い分ける際の簡単なガイドです。
方法 | 適しているケース | 注意点 |
---|---|---|
CSVファイル | 実運用に近い環境でテストしたい場合 | 外部ファイルの管理が必要 |
ヒアドキュメント | 小規模データやシンプルなロジックのテストに最適 | ファイル入出力処理は検証できない |
テンポラリファイル | ファイル入出力の動作をテストしたい場合 | データ量が多い場合はセットアップが少し手間 |
まとめ
この記事では、CSV機能をテストする3つの手法を紹介しました。
- CSVファイルを読み込む方法
- ヒアドキュメントでデータを直接利用する方法
- テンポラリファイルを使う方法
CSVファイルを用意する場合は、変更時にCSVファイルとテストファイルそれぞれの変更が必要になり、ヒアドキュメントやテンポラリファイルの場合は、ある程度の大きさのものを用意しようとすると、大変かつテストファイルが大きくなってしまう問題がありそうです。
どの方法もメリットデメリットが存在するので、要件や状況に応じて最適な方法を選択してみてください。
Discussion