【问题标题】:Rspec and Rails 4, update skip callbackRspec 和 Rails 4,更新跳过回调
【发布时间】:2017-07-13 08:10:36
【问题描述】:

我尝试使用 rspec 为我的 rails 应用程序运行更新测试。

我正在使用 rspec 3.5 和 rails 4。

行为应该如下:

当我创建一个具有售价的新服务时,它会创建一个 Price 实例并设置与服务的关系。然后,当我更新我的服务时,如果没有售价,它会破坏价格记录(客户要求节省数据库空间)。 我实现的过程似乎运行良好,当我使用 UI 进行测试并检查价格记录的计数时,它就像假设的那样减少了一个。但是,如果失败,则进行单元测试。

代码如下:

服务控制器:

  def update
    @service.assign_attributes(service_params)

    puts "update method"

    respond_to do |format|
      if @service.valid?
        if params['preview']
          @service.build_previews
          format.js { render 'services/preview' }
        else
          @service.save!
          format.html { redirect_to client_trip_days_path(@client, @trip), notice: t('flash.services.update.notice') }
        end
      else
        format.html { render :edit }
        format.js { render :new }
      end
    end
  end

Service 模型中的回调:

  def create_or_update_price
    puts "in create or update price"
    if selling_price.present? && price.present?
      self.price.update_columns(:trip_id => trip.id, :currency => trip.client.currency, :purchase_price => purchase_price, :selling_price => selling_price)
    elsif selling_price.present? && !price.present?
      self.price = RegularPrice.create(:trip => trip, :currency => trip.client.currency, :purchase_price => purchase_price, :selling_price => selling_price)
    elsif !selling_price.present? && price.present?
      self.price.destroy
    end
  end

测试:

it "updates the lodging and destroy the price" do
    puts "nombre de service avant création : "
    puts Service.count
    puts "nombre de prix avant création : "
    puts Price.count
    lodging = FactoryGirl.create(:lodging_service, selling_price: 200)
    puts "nombre de service après création : "
    puts Service.count
    puts "nombre de prix après création : "
    puts Price.count
    expect(lodging.reload.price).to be_present
    puts "nombre de prix avant update : "
    puts Price.count
    puts "id"
    puts lodging.id
    patch :update, client_id: client.id, trip_id: trip.id, id: lodging.to_param, service: valid_attributes_no_more_price
    # patch :update, client_id: client.id, trip_id: trip.id, id: lodging.id, service: valid_attributes_with_price
    puts "nombre de prix après update : "
    puts Price.count
    # expect{
    #   patch :update, client_id: client.id, trip_id: trip.id, id: lodging.id, service: valid_attributes_no_more_price
    # }.to change(RegularPrice, :count).by(0)
    expect(lodging.reload.price).to be_nil
  end

  let(:valid_attributes_no_more_price) {
attributes_for(:lodging_service, trip: trip, selling_price: "")

}

如您所见,由于我试图找出问题所在,因此出现了很多 put。

输出是: 服务前卫的名称: 0 nombre de prix avant création : 0 在创建或更新价格 服务后创建的名称: 1 名称 après création : 1 nombre de prix avant 更新: 1 ID 10 nombre de prix après 更新: 1

失败/错误:expect(lodging.reload.price).to be_nil

   expected: nil
        got: #<RegularPrice id: 2, label: nil, currency: "CHF", selling_price: 200.0, priceable_type: "Service", p...ated_at: "2017-07-13 08:08:47", quantity: 1, type: "RegularPrice", position: 1, purchase_price: nil>

如我们所见,更新后似乎没有触发回调,也没有到达控制器中的操作。

你知道出了什么问题吗?

谢谢:)

PS:我的问题中总是无法包含代码,是否有关于如何制作它的教程?

【问题讨论】:

  • 对于本教程,当您提出或回答问题时,会有一个“?”编辑器右上角(在工具栏上)的图标,如果单击它,您可以查看一些快速帮助和“高级帮助”链接,您是否浏览并阅读了这些?
  • 您的问题解决了吗?

标签: ruby-on-rails rspec factory-bot


【解决方案1】:

由于你没有提到你的 ruby​​ 版本,我假设它是 2。

首先,您需要学习如何正确调试代码,以便自己解决问题。

这是你必须做的:

1.将pry gem 添加到您的应用程序中,pry-byebug 还有一个 ruby​​ 1.9.3 版本。

2.在代码中添加断点

it "updates the lodging and destroy the price" do
  (...) # Code here.

  binding.pry # The debugger  will open a console at this point   

  (...) # Maybe more code here
end

3.验证所有变量及其值,看看问题出在哪里

如果您在期望将其添加到方法的第一行之后之前在您的 rspec 文件中找不到 binding.pry 的问题,您可以通过在打开的控制台中键入 next 来逐步调试撬(这将是你的 Rails 服务器运行的地方)。 如果这仍然没有帮助,请尝试在您的课程中添加 binding.pry 并查看其中的状态。

现在花几分钟/几小时来学习调试,从长远来看,它将为您节省数天/数周的时间。 (当你在学习时,你并不真正知道程序应该如何运行,额外的知识是无价的,过了一段时间你只需要一个调试器来解决极其复杂的问题)。

【讨论】:

  • 我按照你的解释,但错误仍然存​​在。当我在 rspec 文件中使用 binding.pry 时,变量都是商品。当我把它放在控制器的更新方法中时,它什么也不做。当我将它放入模型中时,它会在创建时升高,但不会在更新时升高。问题似乎是补丁 :update 没有转到控制器的更新方法有没有办法显示 rspec 发出的所有 url 请求?感谢您的帮助
  • 我不知道是否有命令,但是如果您在 patch: 之前添加 binding.pry,您将能够在那里插入 pry 控制台并执行 step 哪个将带您进入请求,在那里您可以通过next 和用户self 等获取更多信息。
  • 另外,我建议您尝试在控制器的所有方法中添加调试点,看看哪个会被命中。不知道为什么你的更新方法没有命中,是不是把binding.pry加到方法的第一行了?
猜你喜欢
  • 1970-01-01
  • 2012-02-03
  • 2011-11-26
  • 1970-01-01
  • 2016-10-29
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多