Ruby on rails Rspec规范更新操作失败

Ruby on rails Rspec规范更新操作失败,ruby-on-rails,rspec,Ruby On Rails,Rspec,我有以下要求规范 it "updates an open time" do # Create an OpenTime open_time = OpenTime.create(:start_time => (Time.now + 2.hours), :end_time => (Time.now + 10.hours)) # Build an open_time update param params = {:open_time => {:start_time =&

我有以下要求规范

it "updates an open time" do
  # Create an OpenTime
  open_time = OpenTime.create(:start_time => (Time.now + 2.hours), :end_time => (Time.now + 10.hours))
  # Build an open_time update param
  params = {:open_time => {:start_time => (Time.now + 5.hours)}}
  # Send param to open_times#update
  put open_time_path(open_time.id) , params
  # Check to see if OpenTime was updated
  open_time.should_receive(:update_attributes).with({:start_time => (Time.now + 5.hours)})
end
这是我的开放时间控制器

def update
  @open_time = OpenTime.find(params[:id])
  if @open_time.update_attributes(params[:open_time])
    flash[:success] = "Time updated."
    redirect_to @open_time
  else
    render 'edit'
  end
end 

测试失败,预期:1已接收:0

将接收
更新\u属性的对象不是该对象,而是由
OpenTime返回的新对象。find
,因此,您应该确保find返回您的对象:

OpenTime.stub(:find).and_return(open_time)
open_time.should_receive(:update_attributes).with({:start_time => (Time.now + 5.hours)})
然后:

put open_time_path(open_time.id) , params
另外,我会在测试开始时添加
target\u time=time.now+5.hours
,然后在params和matcher中使用该时间。

注意到,您必须存根OpenTime.find方法,以便在从控制器调用OpenTime实例时返回该实例。将测试代码更改为:

it "updates an open time" do
  target_time = (Time.now + 5.hours)
  # Create an OpenTime
  open_time = OpenTime.create(:start_time => (Time.now + 2.hours), :end_time => (Time.now + 10.hours))

  # Build an open_time update param
  params = {:open_time => {:start_time => target_time}}

  # Stub OpenTime to return your instance
  OpenTime.stub(:find).and_return(open_time)

  # Set expectation on open_time to receive :update_attributes
  open_time.should_receive(:update_attributes).with({:start_time => target_time})

  # Send param to open_times#update
  put open_time_path(open_time.id) , params
end
这里发生的事情是,您构建了OpenTime的实例(open_time),通过截取OpenTime类,您说的是“如果有人在OpenTime类上调用find,则不运行find,而只是返回open_time(您刚刚创建的实例)”。然后对实例设置期望,以接收:update\u属性。当您调用put open\u time\u path(open\u time.id)时,params您的控制器创建操作将处理请求和OpenTime。find(…)将返回您的实例(open\u time)并对其调用:update\u属性


希望它有意义。

尝试运行open\u time.should\u receive(:update\u attributes)。使用({:start\u time=>(time.now+5.hours)})在放置open\u time\u path(open\u time.id)之前,paramstill会失败,并出现相同的错误:(谢谢!只需更改为
OpenTime.stub(:find)。然后返回(open\u time)open\u time.should\u receive(:update\u attributes!)。使用({“开始时间”=>(time.now+5.hours)。到})
它就过去了!