测试rails控制器的私有方法

时间:2016-05-12 05:27:43

标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails

我目前正在开发一个需要100%代码覆盖率的团队,我不能在我的生活中使用这种单行方法来使我目前的覆盖率达到100%。

我有一个基本控制器,看起来像这个多个其他控制器扩展。

module Owners
  module Pets
    class BaseController < Owners::ApplicationController
      private

      def current_pet
        current_owner.all_pets.find(params[:pet_id])
      end
    end
  end
end

我对此控制器的规范是这样的。

require 'rails_helper'

Rails.describe Owners::Pets::BaseController, type: :controller do
  routes { Owners::Engine.routes }

  controller Owners::Pets::BaseController do
    def index
      current_pet
    end
  end

  let(:user) { double :user, id: 1, owner: nil }

  before { sign_in(user) }

  before do
    allow(request.env['warden']).to receive(:user).and_return user
    allow(Owners::User).to receive(:find).with(user.id).and_return user
  end

  context 'with current owner and pet' do
    let(:owner) { create :owner }
    let(:pet) { create(:owner_pet, owner: owner) }

    describe '#current_pet' do
      before do
        allow(controller).to receive(:current_pet).and_return pet
        routes.append { get 'index' => 'owners/pets/base#index' }
      end

      it do
        get :index
        is_expected.to eq pet
      end
    end
  end
end

规范失败并显示错误“No route matches {:action =&gt;”index“,:controller =&gt;”owners / pets / base“}”Routes.append应该添加正确的路由,对吗?“ / p>

更新:通过将我的routes { Owners::Engine.routes }行移到匿名控制器上方,它不再抛出与路由相关的错误。但是现在它将pet与实际的控制器类进行比较。输出太长而无法在此处粘贴,但它基本上是:

expected: #<Owners::Pet>
got: #<#<Class:0x007fc65c860518>:0x007fc65f83a248>

有一大堆属性和方法。

2 个答案:

答案 0 :(得分:1)

此测试没有价值。你正在测试你正在测试的方法。即使#current_pet的方法体引发异常,测试仍会通过。

通常,最好避免直接测试私有方法。您应该能够通过继承自Owners::Pets::BaseController

的其中一个类间接测试此方法

答案 1 :(得分:0)

当你使用语法qsub dash.sh -l nodes=5 时,Rspec必须推断出什么&#34;它&#34;是基于测试本身。 it { is_expected.to ... }方法可用于明确指定&#34; it&#34;是;在subject不存在的情况下,Rspec将实例化正在测试的类的新实例。在你的情况下,这将是控制器本身。

尝试在subject块的上下文中明确设置subject

例如,

#current_pet

强制性注意:我必须同意其他海报,这个测试不是很有用。传统观念只是测试公共方法(私有方法通过公共方法的使用来测试)。