rspec控制器测试:“预期#count更改为-1,但更改为0”

1 testing rspec ruby-on-rails rspec-rails

无法解决此错误。我不确定controller_spec的哪一部分写错了。请帮忙!

路线

Rails.application.routes.draw do
  resources :cases, only: [:index, :show, :new, :create, :edit, :update] do
    resources :links, only: [:create, :destroy]
  end
end
Run Code Online (Sandbox Code Playgroud)

控制者

class LinksController < ApplicationController

  before_action :prepare_case

  def destroy
    @link = @case_file.links.find(params[:id])
    @link.destroy
    redirect_to case_path(@case_file)
  end

  private

  def prepare_case
    @case_file = CaseFile.find(params[:case_id])
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/工厂

FactoryGirl.define do

  factory :link do

    case_file
    url 'www.google.com'

    trait :invalid do
      case_file nil
      url ''
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/控制器

require 'rails_helper'

RSpec.describe LinksController, type: :controller do

  let(:user) { build(:user) }
  before { login_user user }
  #for user log in

  let(:case_file) { create(:case_file) }
  let(:link) { create(:link, case_file: case_file) }

  describe "DELETE destroy" do
    it "deletes a link" do
      expect { delete :destroy, id: link.id , case_id: case_file }.
      to change(Link, :count).by(-1) 
      expect(response).to redirect_to(case_path(case_file))
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

错误信息

$ rspec规范/控制器/links_controller_spec.rb ... F

失败:

1)LinksController DELETE destroy删除链接失败/错误:期望{delete:destroy,id:link.id,case_id:case_file}。更改(Link,:count).by(-1)

预期#count已更改为-1,但已更改为0#./spec/controllers/links_controller_spec.rb:28:在“

在1.18秒内完成(文件加载时间为5.03秒)4个示例,其中1个失败

失败的例子:

rspec ./spec/controllers/links_controller_spec.rb:27#LinksController DELETE destroy删除链接

Fre*_*ung 6

这是一个经典的错误(尽管我找不到很好的副本)。当您使用letrspec时,仅Link当您首次引用该对象时,才执行关联的块(在您的情况下创建该对象)。

结果,链接在传递给的块中创建和销毁expect:计数不变,并且测试失败。

您需要做的只是link在测试的早期参考。link如果您使用let!而不是letRspec 而不是仅将随机调用添加到测试中的某个位置,则rspec将在示例运行并通过测试之前创建对象。这和做的一样

before(:example) { link }
Run Code Online (Sandbox Code Playgroud)