- モデルは現在のユーザーについて知っているべきではありません (コントローラーはこの概念について知っています)。
- これを User クラスのメソッドとして抽出する必要があります。そうしないと、テストする意味がありません。つまり、なぜアプリ コードにないロジックをテストするのでしょうか?
- 一致したプレーヤーを取得する関数は、現在のユーザーや、さらに言えば他のユーザーについて知る必要はなく、評価だけが必要です。
- それをテストするには、多数の User インスタンスを作成し、メソッドを呼び出して、結果が期待どおりの正しいユーザー インスタンスのリストであることを確認します。
models/user.rb
class User < ActiveRecord::Base
...
def self.matched_players(current_user_rating)
find(:all,
select: ["*,(abs(rating - #{current_user_rating)) as match_strength"],
order: "match_strength",
limit: 5)
end
...
end
仕様/モデル/user_spec.rb
describe User do
...
describe "::matched_players" do
context "when there are at least 5 users" do
before do
10.times.each do |n|
instance_variable_set "@user#{n}", User.create(rating: n)
end
end
it "returns 5 users whose ratings are closest to the given rating, ordered by closeness" do
matched_players = described_class.matched_players(4.2)
matched_players.should == [@user4, @user5, @user3, @user6, @user2]
end
context "when multiple players have ratings close to the given rating and are equidistant" do
# we don't care how 'ties' are broken
it "returns 5 users whose ratings are closest to the given rating, ordered by closeness" do
matched_players = described_class.matched_players(4)
matched_players[0].should == @user4
matched_players[1,2].should =~ [@user5, @user3]
matched_players[3,4].should =~ [@user6, @user2]
end
end
end
context "when there are fewer than 5 players in total" do
...
end
...
end
...
end