我不太清楚如何解释这一点。
我有一个运行RSpec 2.8.1的现有Rails 3.1.3应用程序,带有284个测试的测试套件。他们会一遍又一遍地愉快地执行。
我今天为用户更新了他们的设置添加了一项新测试 -
require 'spec_helper'
describe UserSettingsController do
describe 'PUT "update"' do
let!(:user) { Fabricate :user }
it 'updates the User with the correct attributes' do
proxy = double('proxy') #.as_null_object
controller.should_receive(:current_user).any_number_of_times { proxy }
attributes = Fabricate(:user_settings).stringify_keys
proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }
login_user(user)
put :update, :user => attributes
end
end
end
最初这个测试失败了,因为我的application_controller.rb中有一个before_filter,它也引用了current_user(这会在mock上产生意外的消息),所以我想把mock作为一个空对象(参见上面注释掉的区域)。
当我这样做时...整个测试套件在完成测试后(但在继续下一个测试之前)就像在无限循环中一样挂起。
以前有人见过这样的事吗?我是否正确使用.as_null_object?
编辑以澄清一些事情,login_user
是Sorcery提供的用于在测试中进行身份验证的帮助程序,:user_settings
制造商只是使用时区制作哈希在它。
答案 0 :(得分:1)
除非你:user_settings
工厂是自我指涉的,否则我会考虑做两件事。第一:
describe UserSettingsController do
describe 'PUT "update"' do
let(:proxy) { double('proxy').as_null_object }
let(:user) { Fabricate :user }
before(:each) do
login_user(user)
end
it 'updates the User with the correct attributes' do
controller.should_receive(:current_user).any_number_of_times { proxy }
attributes = Fabricate(:user_settings).stringify_keys
proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }
put :update, :user => attributes
end
end
end
如果这样失败,你就会知道问题出在魔法内部。 (你永远不会在控制台中看到示例摘要字符串输出。)请注意,我保留了#as_null_object
调用:sorcery会刺激被模拟的用户获取信息,主要是填充哈希值。如果您有兴趣,请开始阅读here。如果 无法帮助查明问题,请考虑完全删除login_user
。像这样:
describe UserSettingsController do
describe 'PUT "update"' do
let(:proxy) { double('proxy') }
let(:user) { Fabricate :user }
it 'updates the User with the correct attributes' do
controller.should_receive(:current_user).any_number_of_times { proxy }
attributes = Fabricate(:user_settings).stringify_keys
proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }
put :update, :user => attributes
end
end
end
你将current_user
存根到控制器定义,我认为意味着你会超过你的before_filter auth钩子,将current_user
定义为proxy
}。如果在所有调用中都发生了一些愚蠢的事情,那么你至少会减少一些调用。
我还在猜测 - 我没有构建一个示例应用程序。祝你好运。