2

我无法将我的测试与 Rails 分离。例如,如何存根在current_user下面的帮助程序中调用的方法(来自 Devise)?

辅助模块:

module UsersOmniauthCallbacksHelper

  def socialmedia_name(account)
    name = current_user.send(account)['info']['name']
    name = current_user.name if name.blank?
    name
  end

end

测试

require_relative '../../app/helpers/users_omniauth_callbacks_helper.rb'

describe 'UsersOmniauthCallbacksHelper' do
  include UsersOmniauthCallbacksHelper

  describe '#socialmedia_name(account)' do
    it 'should return the users name listed by the social media provider when that name is provided' do

      #once I've done away spec_helper, this next line ain't gonna fly.
      helper.stub(:current_user) { FactoryGirl.create(:user, facebook:  {"info"=>{"name"=>"Mark Zuckerberg"}}) }

      socialmedia_name('facebook').should == "Mark Zuckerberg"
    end
  end
end

如何存根current_user在类中使用的方法?

如果我正在加载 Rails,测试仍然可以保留我的helper.stub(:current_user). 但很自然,现在这行不通,因为我没有加载 spec_helper 文件。

4

2 回答 2

2

对于测试模块,您最好的选择是将帮助程序包含到测试类中,创建一个新实例,然后从那里存根方法。此外,您应该将更多的名称逻辑移动到模型中,这样您就不需要让助手知道send(account),并且它的返回是一个哈希,它有一个哈希(德米特法则)。我希望几乎所有的 socialmedia_name 方法都在模型中。例如:

describe 'UsersOmniauthCallbacksHelper' do
  let(:helper) do
    Class.new do
      include UsersOmniauthCallbacksHelper
      attr_accessor :current_user
    end.new
  end
  let(:user) { stub('user') }

  before do
    helper.current_user = user
  end

  describe '#socialmedia_name(account)' do
    it 'should return the users name listed by the social media provider when that name is provided' do
      # stub user here

      helper.socialmedia_name('facebook').should == "Mark Zuckerberg"
    end
  end
end
于 2013-01-26T18:05:12.330 回答
0

这是我最终得到的结果(在根据 Jim 的建议重构代码之前)。最重要的是,测试运行得非常快。这个助手可能会改变,但我将在我的更多工作中使用这种无轨策略。

#spec/helpers/users_omniauth_callbacks_helper_spec.rb

require_relative '../../app/helpers/users_omniauth_callbacks_helper.rb'
require 'active_support/core_ext/string'

describe 'UsersOmniauthCallbacksHelper' do
  let(:helper) do
    Class.new do
      include UsersOmniauthCallbacksHelper
      attr_accessor :current_user
    end.new
  end

  describe '#socialmedia_name(account)' do
    it 'should return the users name listed by the social media provider when that name is provided' do
      helper.current_user = stub("user", :facebook =>{"info"=>{"name"=>"Mark Zuckerberg"}}) 
      helper.socialmedia_name('facebook').should == "Mark Zuckerberg"
    end

    it 'should return the current users name when the social media data does not provide a name' do
     helper.current_user = stub("user", name: "Theodore Kisiel", facebook: {"info"=>{}}) 
      helper.socialmedia_name('facebook').should == "Theodore Kisiel"
    end
  end
end
于 2013-01-28T14:38:40.313 回答