Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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方法被称为2X,但可以';我找不到第二次了_Ruby On Rails_Ruby On Rails 4_Rspec_Controller_Rspec Rails - Fatal编程技术网

Ruby on rails Rspec方法被称为2X,但可以';我找不到第二次了

Ruby on rails Rspec方法被称为2X,但可以';我找不到第二次了,ruby-on-rails,ruby-on-rails-4,rspec,controller,rspec-rails,Ruby On Rails,Ruby On Rails 4,Rspec,Controller,Rspec Rails,这是我的控制器规格 before do @order = Order.new end it "should call find & assign_attributes & test delivery_start methods" do Order.should_receive(:find).with("1").and_return(@order) Order.any_instance.should_receive(:assign_attributes).w

这是我的控制器规格

before do
    @order = Order.new
end
it "should call find & assign_attributes & test delivery_start methods" do
    Order.should_receive(:find).with("1").and_return(@order)
    Order.any_instance.should_receive(:assign_attributes).with({"id"=>"1", "cancel_reason" => "random"}).and_return(@order)
    Order.any_instance.should_receive(:delivery_start).and_return(Time.now)
    post :cancel, order: {id:1, cancel_reason:"random"}
end
失败在于:

Failure/Error: Unable to find matching line from backtrace
   (#<Order:0x007fdcb03836e8>).delivery_start(any args)
       expected: 1 time with any arguments
       received: 2 times with any arguments
 # this backtrace line is ignored

我建议更多的期望值,并根据您的使用返回真或假。考虑下面的变化

class SomeController < ApplicationController
  def cancel
    ...
    if refundable?
      ...
    end
  end

  private

  def refundable?
    (@order.delivery_start - Time.now) > 24.hours
  end
end

# spec/controllers/some_controller_spec.rb
describe SomeController, type: :controller do
  describe '#cancel' do
    context 'when refundable' do
      it 'cancels and refunds order' do
        order = double(:order)
        params = order: {id: '123', cancel_reason: "random"}
        expect(Order).to receive(:find).with('123').and_return(order)
        expect(order).to receive(:assign_attributes).with(params[:order]).and_return(order)
        expect(controller).to receive(:refundable?).and_return(true)
        expect(controller).to receive(:refund).and_return(true)
        expect(order).to receive(:save).and_return(true)
        post :cancel, params
        expect(response).to redirect_to '/your_root_path'
        expect(session[:flash]['flashes']).to eq({'success'=>'Your order has been successfully cancelled & refunded'})
        expect(assigns(:order)).to eq order
      end
    end
  end
end
class SomeController24.5小时
结束
结束
#等级库/控制器/某些控制器等级库rb
描述SomeController,type::controller do
描述“#取消”做什么
上下文“何时可退款”如何
它“取消并退还订单”吗
订单=双(:订单)
params=顺序:{id:'123',取消原因:“随机”}
预期(订单)。接收(:查找)。带有('123')。和返回(订单)
预期(订单)。接收(:分配属性)。使用(参数[:订单])和返回(订单)
期望(控制器)。接收(:可退款?)和返回(真)
期望(控制器)。接收(:退款)。和返回(真)
预期(订单)。接收(:保存)。并返回(true)
post:取消,参数
期望(响应)。将\u重定向到“/您的\u根\u路径”
预期(会话[:flash]['flash'])。到eq({'success'=>'您的订单已成功取消并退款'})
expect(分配(:订单))到eq订单
结束
结束
结束
结束

我建议您测试行为,而不是实现。虽然在某些情况下,您可能希望删除数据库,但在控制器规范中这样做并不是一个好主意,因为您正在测试控制器和模型层之间的集成

此外,您的测试只是真正测试控制器如何完成其工作,而不是实际完成

describe SomeController, type: :controller do

  let(:order){ Order.create } # use let not ivars.

  describe '#cancel' do

    let(:valid_params) do
      { order: {id: '123', cancel_reason: "random"} }
    end

    context 'when refundable' do
      before { post :cancel, params }
      it 'cancels the order' do
        expect(order.reload.cancel_reason).to eq "random"
        # although you should have a model method so you can do this:
        # expect(order.cancelled?).to be_truthy
      end

      it 'redirects and notifies the user' do
         expect(response).to redirect_to root_path
         expect(flash[:success]).to eq 'Your order has been successfully cancelled & refunded'
      end
    end
  end
end

抱歉,这是一个非常不令人满意的答案,但我重新启动了我的计算机,规范通过了


有一件事以前对我来说很讨厌,那就是我忘了保存代码,也就是说,测试所针对的代码的旧版本被调用了两次
delivery\u start
。但在这种情况下,我肯定检查了我是否保存了。我不知道为什么重启会修复它…

抱歉,但它“应该调用查找和分配属性以及测试交付启动方法”执行顺序。应该接收(:find)。使用(“1”)。和返回(@Order)顺序。任何实例。应该接收(:分配属性)。使用({“id”=>“1”,“取消原因”=>“random”))和返回(@Order)Order.any_instance.project_receive(:delivery_start)and_return(Time.now)post:cancel,Order:{id:1,cancel_reason:“random”}endI不确定,但我猜
delivery_start
可能会在显示的视图中合理地显示出来?这是我对第二个“调用”来自何处的猜测。@TarynEast没有调用
delivery\u start
的关联视图,值得检查:)Max,这是一个公平的评论,但在本例中,测试是这样设置的。还有其他规范正在检查控制器的方法是否按照预期的方式工作。是吗?如果你不想修复它,为什么要问?但是,嘿,这是你的应用程序。。。我的问题不是如何改变测试的性质,而是为什么一个特定的规范可能没有通过——有时是修复bug的最佳方法。。。首先是要找到一种完全不同的更好的方法:D
describe SomeController, type: :controller do

  let(:order){ Order.create } # use let not ivars.

  describe '#cancel' do

    let(:valid_params) do
      { order: {id: '123', cancel_reason: "random"} }
    end

    context 'when refundable' do
      before { post :cancel, params }
      it 'cancels the order' do
        expect(order.reload.cancel_reason).to eq "random"
        # although you should have a model method so you can do this:
        # expect(order.cancelled?).to be_truthy
      end

      it 'redirects and notifies the user' do
         expect(response).to redirect_to root_path
         expect(flash[:success]).to eq 'Your order has been successfully cancelled & refunded'
      end
    end
  end
end