正解は「toBeは参照の同一性を比較するため失敗する」です。toBeは内部的にObject.is(==や===に近い厳密比較)を使っており、プリミティブ値には有効ですが、オブジェクトや配列に対しては「同じメモリ上の参照か」を見ます。コード中のuserと、expectに渡したオブジェクトリテラルは、たとえプロパティが全く同じでも別物として生成されているため、参照が一致せずテストは失敗します。中身を比較したいときはtoEqualを使うのが正解で、これなら再帰的にプロパティを見てくれます。他の選択肢について、expectはあらゆる値を受け取れますし、Vitestが暗黙に深い比較をすることもありません。toBeとtoEqualの使い分けで迷わないためにこのマッチャの使い分けは、Vitest(やJest)を触り始めた人が最初につまずくポイントです。ざっくり覚えるなら次の通りです。toBe: 数値・文字列・真偽値などのプリミティブ、または「同じ参照であること」を確認したいときtoEqual: オブジェクトや配列の中身が一致しているかを確認したいとき// OK: プリミティブはtoBeでよい expect(1 + 1).toBe(2) // NG: 別オブジェクトなので失敗する expect({ a: 1 }).toBe({ a: 1 }) // OK: 構造的に等しいかを比較 expect({ a: 1 }).toEqual({ a: 1 })なぜこの設計になっているのか「最初からtoEqualだけでよいのでは?」と感じるかもしれませんが、参照の同一性を確認したい場面は実際にあります。たとえばReactのuseMemoやuseCallbackが本当にメモ化されているか、シングルトンが同じインスタンスを返しているかをテストしたいとき、toBeで参照が一致することを確認します。一方で、APIレスポンスやReducerの戻り値など、新しく生成されたオブジェクトの構造を検証したい場面ではtoEqualが必要になります。「参照の等価性」と「値の等価性」は別物だというJavaScriptの基本が、マッチャの選択にそのまま反映されているわけです。undefinedを無視したい場合はtoStrictEqualさらに厳密に比較したいときはtoStrictEqualが使えます。toEqualは{ a: 1, b: undefined }と{ a: 1 }を等しいと見なしますが、toStrictEqualはこれを区別し、クラスインスタンスの型の違いも検出します。意図せずundefinedが混入しているバグを拾いたい場面では、toStrictEqualを選ぶと安心です。