Rspec规范在更新操作时失败

时间:2013-03-07 21:47:54

标签: 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 => (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

这是我的open_times控制器

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

2 个答案:

答案 0 :(得分:1)

不是那个会收到update_attributes的对象,而是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_time = Time.now + 5.hours,然后在params和matcher中使用该时间。

答案 1 :(得分:1)

正如kr1注意到,当从控制器调用OpenTime时,你必须存根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_attributes。当您调用 put open_time_path(open_time.id),params 时,您的控制器创建操作将处理请求,OpenTime.find(...)将返回您的实例(open_time)并在其上调用:update_attribute。 / p>

希望它有意义。

相关问题