Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用Rspec-should\u-receive测试控制器是否正确调用对象上的方法_Ruby On Rails_Ruby_Ruby On Rails 4_Rspec_Rspec Rails - Fatal编程技术网

Ruby on rails 使用Rspec-should\u-receive测试控制器是否正确调用对象上的方法

Ruby on rails 使用Rspec-should\u-receive测试控制器是否正确调用对象上的方法,ruby-on-rails,ruby,ruby-on-rails-4,rspec,rspec-rails,Ruby On Rails,Ruby,Ruby On Rails 4,Rspec,Rspec Rails,好的,首先,我应该说,虽然我已经读了很多关于应该接收,但我仍然不能完全确定我是否理解它背后的概念,因此我所做的可能是完全不可能的 我有以下资料: class PlansController def destroy plan = plan.find_by_id(params[:id]) if plan.cancel_stripe_subscription(params[:reason]) flash[:success] = "success" redir

好的,首先,我应该说,虽然我已经读了很多关于
应该接收
,但我仍然不能完全确定我是否理解它背后的概念,因此我所做的可能是完全不可能的

我有以下资料:

class PlansController
  def destroy
    plan = plan.find_by_id(params[:id])
    if plan.cancel_stripe_subscription(params[:reason])
      flash[:success] = "success"
      redirect_to root_path
    else
      #error handling
    end
  end
end

class Plan
  def cancel_stripe_subscription(reason)
    self.status = "canceled"
    self.cancellation_reason = reason
    if self.save
      return true
    else
      return false
    end
  end
在我的控制器规范中,我认为有必要进行一项测试,即使用正确的参数和所有内容成功调用
cancel\u stripe\u subscription
方法(使用1 should\u receive1),并进行另一项测试,以确保
destroy
操作的输出正确

换句话说,我想编写以下控制器规范:

describe PlansController, "Destroy Action" do
  before do
    @plan = Plan.create(...)
  end
  it "should have called destroy action" do
    delete :destroy,
      plan: {
        id: @plan.id,
        reason: "something"
      }
      assigns(:plan).should_receive(:cancel_stripe_subscription).with(reason:"something").exactly(1).times.and_return(true)
  end

  it "should have called destroy action" do
    delete :destroy,
      plan: {
        id: @plan.id,
        reason: "something"
      }
    assigns(:plan).status.should == "canceled"
    assigns(:plan).cancellation_reason.should == "something"
  end
end
第二个测试通过,但第一个测试抛出

Failure/Error: assigns(:plan).should_receive(:cancel_stripe_subscription)
   (#<Plan:0x007fe282931310>).cancel_stripe_subscription(*(any args))
       expected: 1 time with any arguments
       received: 0 times with any arguments
失败/错误:分配(:计划)。是否应接收(:取消订阅)
(#)取消订阅(*(任何参数))
预期:1次,有任何参数
收到:0次,有任何参数
所以我有两个问题:

  • 我只是想确认一下,我是否正确使用了
    是否应该接收
    ?我应该测试一下吗?或者第二次测试被普遍认为足够了
  • 如果我应该为此进行测试,那么正确的使用方法是什么?(注意,
    expect(@plan)的运气不好。收到(:取消订阅)

  • 在调用测试中的方法之前,必须设置
    应该接收的
    期望值;你以后再定。由于您需要在之前进行设置,因此您必须确保设置了期望的对象最终在操作中被操作。通常的方法是在
    计划
    上删除
    按id查找,如下所示:

    it "should have called destroy action" do
      Plan.stub(:find_by_id).and_return(@plan)
      assigns(:plan).should_receive(:cancel_stripe_subscription).with(reason:"something").exactly(1).times.and_return(true)
      delete :destroy, plan: { id: @plan.id, reason: "something" }
    end
    
    (我假设您打算编写
    plan=plan.find by_id(params[:id])
    destroy
    操作的第一行。)


    至于你是否应该以这种方式进行测试,我想说你的第二次测试在验证你想要的结果方面做得足够好,而且你真的不需要费事。

    我认为这里的混乱部分是由于结合了两种不同的测试风格,mockist(你的第一次测试)和Classisist(你的第二次测试). 根据您喜欢的测试风格,可以使用其中一种,但同时使用这两种方法来测试同一段代码有点多余。

    好的,我想我在这里有点过于密集,我不完全确定我是否理解其中的差异。my way和your way都会先调用
    delete:destroy
    ,然后检查
    分配(:plan)。应该接收
    ,这样就不会有什么不同了。但是当我使用创建的
    @plan
    时,您正在存根一个
    计划。这是否意味着必须将plan对象存根为should\u receive
    才能工作,因为否则您可能已经在真实的
    @plan
    对象上调用了该方法,因此它不再是可测试的?我说得通吗?你很困惑,因为我犯了一个错误,把陈述的顺序弄错了。现在修好了。:)哦,这对我来说太奇怪和不舒服了。。。我将继续我的第二次测试(谢谢!