4

RSpec仕様ファイルには、次のテストがあります

it 'should return 5 players with ratings closest to the current_users rating' do
  matched_players = User.find(:all, 
                              :select => ["*,(abs(rating - current_user.rating)) as player_rating"], 
                              :order => "player_rating", 
                              :limit => 5)

  # test that matched_players array returns what it is suppose to 
end

Matched_players が正しいユーザーを返していることをテストするには、これをどのように完了すればよいでしょうか。

4

2 に答える 2

4

最初に何人かのテスト ユーザーをテスト DB に紹介し (たとえば、ファクトリを使用)、その後、テストが正しいユーザーを返すことを確認する必要があると思います。

また、一致したユーザーを返すメソッドをモデルに含める方が理にかなっています。

例えば:

describe "Player matching" do
  before(:each) do
    @user1 = FactoryGirl.create(:user, :rating => 5)
    ...
    @user7 = FactoryGirl.create(:user, :rating => 3)
  end

  it 'should return 5 players with ratings closest to the current_users rating' do
    matched_players = User.matched_players
    matched_players.should eql [@user1,@user3,@user4,@user5,@user6]
  end
end
于 2013-06-20T09:04:22.663 に答える
1
  • モデルは現在のユーザーについて知っているべきではありません (コントローラーはこの概念について知っています)。
  • これを 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
于 2013-06-20T09:54:58.803 に答える