Ruby on Rails 3 - 如何使用查找和日期条件进行测试



我正在尝试为一种方法开发一些测试,该方法负责检索在某个日期之后创建的一些用户。我不知道如何模拟测试。方法如下:

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

问题是它总是返回所有用户,尽管只返回一个。(最后一个)。 我哪里弄错了?

帮帮我=)

您不是在测试您必须在那里测试的内容,在控制器规范中,您只需要测试您想要的方法是否使用您想要的参数调用,在您的情况下,您必须测试用户模型是否收到 :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

这样,您就可以确保您的操作执行它所做的事情,并且规范速度要快得多,因为您不是在创建用户

然后,您可以在模型规范上测试该方法,

在那里您必须创建一些用户,调用该方法并检查返回的用户(不要在模型规范上存根/模拟任何内容)

您的stub调用告诉find忽略它认为应该做的事情并返回@users。它不会尝试匹配条件。

不幸的是,要进行测试,我认为您必须允许find通过数据库执行,这意味着您不能使用 mock_model s。您可能想要做User.create(...)FactoryGirl.create(:user)(或其他一些工厂/夹具)。

当然,这样做

,如果您使用attr_accessibleattr_protected,您可能会遇到MassAssignment问题,但这些问题很容易stub

我希望这有所帮助。

相关内容

  • 没有找到相关文章

最新更新