🎃
RSpecの`eq`と`be`の違いを完全理解!初心者向け徹底解説
eq
とbe
の違いを完全理解!初心者向け徹底解説
RSpecのRSpecでテストを書いている時、eq
とbe
のどちらを使えばいいか迷ったことはありませんか?この記事では、この2つのマッチャーの違いを具体例とともにわかりやすく解説します。
TL;DR(要約)
-
eq
: 値の等価性をチェック(==
と同じ) -
be
: オブジェクトの同一性をチェック(equal?
と同じ)
基本的な違い
eq
マッチャー
eq
は値の等価性を比較します。Rubyの==
メソッドと同じ動作をします。
# 値が同じかどうかをチェック
expect(1 + 1).to eq(2)
expect("hello").to eq("hello")
expect([1, 2, 3]).to eq([1, 2, 3])
be
マッチャー
be
はオブジェクトの同一性を比較します。Rubyのequal?
メソッドと同じ動作をします。
# 同じオブジェクトかどうかをチェック
str1 = "hello"
str2 = str1
expect(str2).to be(str1) # 同じオブジェクトなのでパス
具体例で理解しよう
文字列の場合
RSpec.describe "文字列の比較" do
it "eqとbeの違い" do
str1 = "hello"
str2 = "hello"
str3 = str1
# 値は同じだが、異なるオブジェクト
expect(str1).to eq(str2) # ✅ パス(値が同じ)
expect(str1).not_to be(str2) # ✅ パス(異なるオブジェクト)
# 同じオブジェクトを参照
expect(str3).to eq(str1) # ✅ パス(値が同じ)
expect(str3).to be(str1) # ✅ パス(同じオブジェクト)
end
end
数値の場合
RSpec.describe "数値の比較" do
it "小さな整数の場合" do
a = 1
b = 1
# 小さな整数はRubyが同じオブジェクトを使い回す
expect(a).to eq(b) # ✅ パス
expect(a).to be(b) # ✅ パス
end
it "大きな整数の場合" do
a = 1000000
b = 1000000
expect(a).to eq(b) # ✅ パス(値が同じ)
expect(a).not_to be(b) # ✅ パス(異なるオブジェクト)
end
end
配列の場合
RSpec.describe "配列の比較" do
it "eqとbeの違い" do
arr1 = [1, 2, 3]
arr2 = [1, 2, 3]
arr3 = arr1
# 値は同じだが、異なるオブジェクト
expect(arr1).to eq(arr2) # ✅ パス(要素が同じ)
expect(arr1).not_to be(arr2) # ✅ パス(異なるオブジェクト)
# 同じオブジェクトを参照
expect(arr3).to be(arr1) # ✅ パス(同じオブジェクト)
end
end
よくある使い分けパターン
eq
1. 通常の値の比較にはRSpec.describe User do
it "ユーザー名が正しく設定される" do
user = User.new(name: "太郎")
expect(user.name).to eq("太郎")
end
end
be
2. オブジェクトの同一性確認にはRSpec.describe "ファクトリーパターン" do
it "シングルトンオブジェクトが同じインスタンスを返す" do
instance1 = Logger.instance
instance2 = Logger.instance
expect(instance1).to be(instance2)
end
end
3. boolean値の場合
RSpec.describe "boolean値のテスト" do
it "truthy/falsyな値のテスト" do
# 真偽値そのものをテスト
expect(user.active?).to be(true)
expect(user.deleted?).to be(false)
# 値の存在をテスト
expect(user.email).to be_truthy
expect(user.deleted_at).to be_falsy
end
end
be
の特殊な使い方
be_truthy
/ be_falsy
# 真偽値の判定
expect("hello").to be_truthy # 空文字列以外は真
expect(nil).to be_falsy # nilは偽
expect(0).to be_truthy # 0は真(JavaScriptとは違う!)
be_nil
# nilかどうかの判定
expect(user.deleted_at).to be_nil
expect(user.deleted_at).not_to be_nil
be_present
/ be_blank
(Rails環境)
# Railsの場合
expect(user.name).to be_present
expect(user.bio).to be_blank
実践的な例:モデルのテスト
RSpec.describe User do
let(:user) { User.new(name: "太郎", email: "taro@example.com") }
describe "#initialize" do
it "正しい値で初期化される" do
# 値の比較にはeq
expect(user.name).to eq("太郎")
expect(user.email).to eq("taro@example.com")
end
it "初期状態が正しく設定される" do
# boolean値の確認にはbe
expect(user.active?).to be(true)
expect(user.admin?).to be(false)
# nilの確認
expect(user.deleted_at).to be_nil
end
end
describe "#duplicate" do
it "異なるオブジェクトが作成される" do
duplicated_user = user.duplicate
# 値は同じ
expect(duplicated_user.name).to eq(user.name)
expect(duplicated_user.email).to eq(user.email)
# でも異なるオブジェクト
expect(duplicated_user).not_to be(user)
end
end
end
まとめ
マッチャー | 用途 | Rubyのメソッド | 例 |
---|---|---|---|
eq |
値の等価性 | == |
expect(1 + 1).to eq(2) |
be |
オブジェクトの同一性 | equal? |
expect(obj1).to be(obj2) |
be_truthy |
真偽値判定 | !!value |
expect("hello").to be_truthy |
be_falsy |
偽値判定 | !value |
expect(nil).to be_falsy |
be_nil |
nil判定 | nil? |
expect(value).to be_nil |
覚え方のコツ
-
値を比較したい →
eq
を使う -
同じオブジェクトか確認したい →
be
を使う -
boolean値をテストしたい →
be(true)
/be(false)
-
存在確認したい →
be_truthy
/be_falsy
/be_nil
適切なマッチャーを選ぶことで、テストの意図が明確になり、保守性の高いテストコードが書けるようになります。最初は迷うかもしれませんが、この違いを意識することで、より良いテストが書けるようになるでしょう!
Discussion