极其奇怪的红宝石'||=' 和 rspec 加倍行为



运行以下rspecgem版本:

* rspec (2.14.1)
* rspec-core (2.14.7)
* rspec-expectations (2.14.5)
* rspec-mocks (2.14.6)
* rspec-rails (2.14.1)

octokit 2.7.1

spec/support/octokit.rb中给定以下内容:

# This support package contains modules for octokit mocking
module OctokitHelper
def mock_pull_requests_for_org org
mock_org_repos(org).map do |repo| 
mock_pull_requests repo 
end.flatten
end
def mock_org_repos org
@@repos ||= [
double('Sawyer::Resource', name: 'repo 1'),
double('Sawyer::Resource', name: 'repo 2')
]
Octokit.stub(:org_repos) { |org=org| @@repos }
@@repos
end
def mock_pull_requests repo, gh_handle=nil
@@pulls ||= [
double('Sawyer::Resource', title: 'pr 1'),
double('Sawyer::Resource', title: 'pr 2')
]
Octokit.stub(:pull_requests) { |repo| @@pulls }
@@pulls 
end
end
RSpec.configure do |config|
config.include OctokitHelper 
end

每当我第一次尝试从规范调用mock_org_repos时,@@repos.first.name就是repo 1。第二次,@@repos.first.name抛出了一个非常奇怪的错误:

1) StudentsController GET #submissions renders pull requests template
Failure/Error: get :submissions, student_id: 2
Double "Sawyer::Resource" received unexpected message :name with (no args)

我使用mock_org_repos:的一个例子

require 'spec_helper'
describe StudentsController do
describe 'GET #submissions' do
before do
@user = FactoryGirl.create(:instructor)
@user.stub(:is_instructor?) { true }
@submissions = mock_pull_requests_for_org ENV['GA_ORG_NAME']
controller.stub(:current_user) { @user }
get :submissions, student_id: 2
end
it 'assigns @submissions' do
assigns(:submissions).should == @submissions
end
it 'renders pull requests template' do
response.should render_template 'submissions'
end
end
end

我的猜测是,您在mock_pull_requests中创建的一个具有相同名称的替身将被发送到:name,但您可以通过确保您的替身具有唯一名称(即double的第一个参数)来检查这一点。

非常感谢rsofaer借给我第二双眼睛来解决这个问题,我想指出现在非常明显的问题:

当通过类变量引用存根时,每次运行示例时,都会"清除"在替身上存根的方法。

这是对RSpec如何在幕后工作的一个非常清晰的解释。

相关内容

  • 没有找到相关文章

最新更新