2016-04-24 105 views
0

我无法解决此错误。我不确定controller_spec的哪个部分写错了。请帮忙!rspec控制器测试:“期望#计数已更改-1,但已更改0”

路线

Rails.application.routes.draw do 
    resources :cases, only: [:index, :show, :new, :create, :edit, :update] do 
    resources :links, only: [:create, :destroy] 
    end 
end 

控制器

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 

规格/工厂

FactoryGirl.define do 

    factory :link do 

    case_file 
    url 'www.google.com' 

    trait :invalid do 
     case_file nil 
     url '' 
    end 
    end 
end 

规格/控制器

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 

错误消息

$ rspec的投机/控制器/ links_controller_spec.rb ... F

失败:

1)LinksController DELETE删除销毁链接 失败/错误: expect {delete:destroy,id:link.id,case_id:case_file }。 改变(链接,:计数)。通过(-1)

预计#COUNT已经由-1变化,但由0 #./spec/controllers/links_controller_spec.rb:28:in`改变块(3级)在'

在1.18秒成品(文件采取5.03秒加载) 4实施例中,1次失败

失败的例子:

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

+0

正在使用这些宝石: 宝石 'rspec的护栏', '〜> 3.0' 宝石 '早该-匹配器', '〜> 3.1' 宝石 'factory_girl_rails' –

回答

3

这是一个典型的错误(虽然我找不到一个很好的副本)。当你使用let时rspec只执行相关的块,在你的情况下创建Link对象,当你第一次引用它。

因此,在传递到expect的块内创建和销毁链接:计数不会改变,测试失败。

您所需要做的只是在测试中早些时候参考link。如果您使用let!而不是let,那么rspec将在示例运行并且您的测试通过之前创建该对象,而不仅仅是在测试中的某个地方添加一个随机调用link。这跟做

before(:example) { link } 
1

我发现你的答案非常有用。我发现更多关于let和let的差异信息! here。这里的关键是让我们懒惰评估。

在这种情况下,我会用let!所以你不需要手动调用该方法。