Rails - 如何从helper规范模拟或访问ApplicationController中定义的方法?

时间:2017-08-27 19:48:52

标签: ruby-on-rails rspec

我正在尝试为Rails帮助程序编写规范。这个助手调用一个方法 在ApplicationController中定义,并通过helper_method公开:

应用/助手/ monkeys_helper.rb

module MonkeysHelper
  def current_monkey_banana_count
    # current_monkey is defined in ApplicationController
    current_monkey.present? ? current_monkey.banana_count : 0 
  end
end

应用/控制器/ application_controller.rb

class ApplicationController < ActionController::Base   
  helper_method :current_monkey

  protected

  def current_monkey
    @current_monkey ||= Monkey.find(session[:monkey_id])
  end
end

如果我从视图中调用current_monkey_banana_count并通过浏览器访问它,它可以正常工作。但是,如果我从这样的规范中调用它:

规格/助手/ monkeys_helper_spec.rb

RSpec.describe MonkeysHelper, type: :helper do
  describe "#current_monkey_banana_count" do
    it "returns 0 if there is no monkey" do
      expect(helper.current_monkey_banana_count).to eq 0
    end
  end
end

然后当我运行规范时出现此错误:

NameError:
       undefined local variable or method `current_monkey' for #<#<Class:0x007fe1ed38d700>:0x007fe1e9c72d88>

Rspec documentation说:

  

要访问您指定的辅助方法,只需调用它们即可   直接在辅助对象上。注意:定义的辅助方法   控制器不包括在内。

知道如何模仿current_monkey或从current_monkey_banana_count内部看到它?

谢谢!

3 个答案:

答案 0 :(得分:0)

也许你可以通过这种方式嘲笑current_monkey来实现这一目标(你已经尝试过了吗?):

RSpec.describe MonkeysHelper, type: :helper do
  let(:monkey) { create(:monkey) }

  before do
    allow(helper).to receive(:current_monkey_user) { monkey }
  end

  # your rest of code
end

干杯!

答案 1 :(得分:0)

View可以调用控制器中定义的辅助方法,因为控制器会自动评估它们,请检查代码here

但您的助手测试并未调用控制器,因此current_monkey模块上MonkeysHelper无效。最佳实践是在辅助类中定义的控制器调用助手中定义的助手,但反之亦然。在您的情况下,您可以将current_monkey移动到MonkeyHelper以便能够对其进行测试。

答案 2 :(得分:0)

我找到了一种(令人讨厌的)方法,但它确实有效:

<强>规格/助手/ monkeys_helper_spec.rb:

require 'rails_helper'

RSpec.describe CartsHelper, type: :helper do
  before do
    def helper.current_monkey; end
  end

  describe "#current_monkey_banana_count" do
    it "returns 0 if there is no cart" do
      expect(helper).to receive(:current_monkey).and_return(nil)
      expect(helper.current_monkey_banana_count).to eq 0
    end

    it "returns monkey.banana_count if there is a monkey" do
      expect(helper).to receive(:current_monkey).and_return(Monkey.create!(banana_count: 5))
      expect(helper.current_monkey_banana_count).to eq 5
    end
  end
end