Rails / AR -如何在rspec中测试::update(id, attributes)



我使用活动记录更新方法来更新多个记录,每个记录都有自己的单独属性。

我用这个控制器代码简化了这一点:

def update
  keys = params[:schedules].keys
  values = params[:schedules].values
  if Schedule.update(keys, values)
    flash[:notice] = "Schedules were successfully updated."
  else
    flash[:error] = "Unable to update some schedules."
  end
  respond_to do |format|
    format.html { redirect_to responsibilities_path }
  end
end

我的问题是,我怎么能测试,而不击中数据库在rspec?

这就是我正在尝试的,但是它不起作用。

describe "PATCH update" do
  it "updates the passed in responsibilities" do
    allow(Schedule)
      .to receive(:update)
      .with(["1", "2"], [{"status"=>"2"}, {"status"=>"1"}])
      .and_return(true)
    # results in
    # expected: 1 time with arguments: (["1", "2"], [{"status"=>"2"}, {"status"=>"1"}])
    # received: 0 times
    # Couldn't find Schedule with 'id'=1
    # without the allow, I get
    # Failure/Error: patch :update, schedules: {
    # ActiveRecord::RecordNotFound:
    #   Couldn't find Schedule with 'id'=1
    # # ./app/controllers/responsibilities_controller.rb:18:in `update'
    # # ./lib/authenticated_system.rb:75:in `catch_unauthorized'
    # # ./spec/controllers/responsibilities_controller_spec.rb:59:in `block (5 levels) in <top (required)>'
    patch :update, schedules: {
      "1" => {
        "status" => "2",
      },
      "2" => {
        "status" => "1",
      }
    }
    expect(Schedule)
      .to receive(:update)
      .with(["1", "2"], [{"status"=>"2"}, {"status"=>"1"}])
    expect(flash[:error]).to eq(nil)
    expect(flash[:notice]).not_to eq(nil)
  end
end

我使用的是Rails 4.2.4和rspec 3.0.0

你的问题是,你期待的是

expect(Schedule)
      .to receive(:update)
      .with(["1", "2"], [{"status"=>"2"}, {"status"=>"1"}])
      .and_call_original     

调用patch方法后。

这意味着请求在断言建立之前到达控制器。为了解决这个问题,只需在补丁调用之前放置expect(Schedule)调用,这也允许您摆脱allow(Schedule)。呼叫。

欢呼。

最新更新