0

ある日付以降に作成されたユーザーを取得するメソッドのテストを開発しようとしています。テストを模擬する方法がわかりません。方法は次のとおりです。

def user_list
  render :nothing => true, :status => 422 if params[:time_param].blank?

  time = Time.parse(params[:time_param])
  @users = User.find(:all, :select => 'id, login, email',
                           :conditions => ["created_at > ?", time])
  render :json => { :users => @users }
end

終わり

これは私の仕様です:

describe UsersController do
  context "when receiving time parameter" do
    before (:each) do
      @time_param = "2013-01-25 00:01:00"
      user1 = mock_model(User, :created_at => Time.parse('2013-01-25 00:00:00'))
      user2 = mock_model(User, :created_at => Time.parse('2013-01-25 00:01:00'))
      user3 = mock_model(User, :created_at => Time.parse('2013-01-25 00:02:00'))

      @users = []
      @users << user1 << user2 << user3
    end

    it "should retrieve crimes after 00:01:00 time" do
      User.stub(:find).with(:all, :select => 'id, login, email').and_return(@users)
      get :user_list, { :time_param => @time_param }
      JSON.parse(response.body)["users"].size.should eq 1
    end
  end
end

問題は、1人だけを返すにもかかわらず、常にすべてのユーザーを返すことです。(最後のもの)。どこを間違えているの?

助けて=)

4

2 に答える 2

1

そこでテストする必要があるものをテストしていません。コントローラーの仕様では、必要なメソッドが必要なパラメーターで呼び出されることをテストするだけで済みます。この場合、ユーザーモデルが:findを受け取ることをテストする必要があります。パラメータ:all、:select =>'id、login、email'、:conditions => ["created_at>?"、time](時間とともにそこにあるはずの値)。

また、そのロジックはコントローラーに属していないため、Userにクラスメソッドを設定する必要があります。たとえば、select_for_json(date)のように、そのfindメソッドをラップアラウンドします(より適切な名前を見つけることができます)。

次に、コントローラーは次のようになります。

def user_list
  render :nothing => true, :status => 422 if params[:time_param].blank?

  time = Time.parse(params[:time_param])
  @users = User.select_for_json(time)
  render :json => { :users => @users }
end

あなたのスペックは

before(:each) do
  @users = mock(:users)
  @time_param = "2013-01-25 00:01:00"
end

it "retrieve users for json" do
  User.should_receive(:select_for_json).once.with(@time).and_return(@users)
  get :user_list, { :time_param => @time }
  assigns(:users).should == @users
end

そうすれば、ユーザーを作成していないため、アクションが実行し、仕様が大幅に高速化されることが確実になります。

次に、モデル仕様でそのメソッドをテストできます。そこで、いくつかのユーザーを作成し、そのメソッドを呼び出して、返されたユーザーを確認する必要があります(モデル仕様で何もスタブ/モックしないでください)

于 2013-01-26T02:36:40.130 に答える
0

Your stub call is telling find to ignore what it thought it was supposed to do and return @users instead. It will not attempt to match the conditions.

Unfortunately, to do your test I think you're going to have to allow the find to execute through your database which means you can't use mock_models. You probably will want to do either User.create(...) or FactoryGirl.create(:user) (or some other factory / fixture).

Of course doing it this way, you may hit MassAssignment issues if you use attr_accessible or attr_protected, but those are easy enough to stub out.

I hope that helps.

于 2013-01-25T17:02:16.387 に答える