如何存根env[';warden';].ApplicationCable::Connection tests with rspec的用户
轨道5.2 我有以下ApplicationTable::Connection ruby文件:如何存根env[';warden';].ApplicationCable::Connection tests with rspec的用户,rspec,devise,rspec-rails,actioncable,Rspec,Devise,Rspec Rails,Actioncable,轨道5.2 我有以下ApplicationTable::Connection ruby文件: module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if verified_user = env['warden'].user
verified_user
else
message = "The user is not found. Connection rejected."
logger.add_tags 'ActionCable', message
self.transmit error: message
reject_unauthorized_connection
end
end
end
end
它失败于:
失败/错误:如果已验证_user=env['warden']。用户
命名错误:
nil:NilClass的未定义方法“[]”
所以我想去掉env['warden'].用户代码并返回一个325的id。
我尝试了以下方法:
allow(env['warden']).to receive(:user).and_return(325)
但这产生了以下错误:
未定义的局部变量或方法
env'
如何测试这个类?试试这个:
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
let(:user) { instance_double(User, id: 325) }
let(:env) { instance_double('env') }
context 'with a verified user' do
let(:warden) { instance_double('warden', user: user) }
before do
allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
allow(env).to receive(:[]).with('warden').and_return(warden)
end
it "successfully connects" do
connect "/cable", headers: { "X-USER-ID" => 325 }
expect(connect.current_user.id).to eq 325
end
end
context 'without a verified user' do
let(:warden) { instance_double('warden', user: nil) }
before do
allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
allow(env).to receive(:[]).with('warden').and_return(warden)
end
it "rejects connection" do
expect { connect "/cable" }.to have_rejected_connection
end
end
end
这是对你的问题的一个很好的解释 问题是关于控制器测试的,但实际上是类似的 我也不认为您应该访问控制器中的低级
env['warden']
。如果gem的作者决定改变这一点,你将不得不修复你的应用程序。
可能warden对象是使用此配置初始化的,并且应该有一个可用的对象(只是在运行规范时不需要,如上面的链接所述)。谢谢您的代码。我尝试了这一点,得到了以下错误:NameError:uninitialized constant ConnectionUpdated<代码>连接应该是
应用程序表::连接
。另外,我修复了env
mock的另一个问题。我做了更改,现在我得到的是ApplicationTable::Connection未实现:envI已使用我根据您的答案修改的代码编辑了您的答案,以通过测试。我还不知道如何解决这件臭气熏天的事。这两项测试现在如预期的那样通过了。我希望你不介意我编辑你写的代码。很高兴你能工作!而且,我很高兴我能帮上忙!我不担心那气味。众所周知,控制器(显然还有电缆)很难模拟,因为Rails控制实例化,所以您不能注入测试双精度。这就是为什么RSpec有允许任何实例的原因。对不起,我一直提到控制器,这是关于动作电缆的。但从概念上讲,这些是同一层,所以在我看来,我们可以使用控制器的“概念”来讨论它们。谢谢。我已经根据许多站点(如)上概述的实践设置了ApplicationTable::Connection。我只是想知道是否有一种方法可以通过去掉这个方法来测试它。我认为你发送的链接是相关的,可能是我无法进行此测试的原因。
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
let(:user) { instance_double(User, id: 325) }
let(:env) { instance_double('env') }
context 'with a verified user' do
let(:warden) { instance_double('warden', user: user) }
before do
allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
allow(env).to receive(:[]).with('warden').and_return(warden)
end
it "successfully connects" do
connect "/cable", headers: { "X-USER-ID" => 325 }
expect(connect.current_user.id).to eq 325
end
end
context 'without a verified user' do
let(:warden) { instance_double('warden', user: nil) }
before do
allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
allow(env).to receive(:[]).with('warden').and_return(warden)
end
it "rejects connection" do
expect { connect "/cable" }.to have_rejected_connection
end
end
end