如何使用 rspec 存根 env['warden'].user 进行 ApplicationCable::Connection 测试
How to stub env['warden'].user for ApplicationCable::Connection tests with rspec
Rails 5.2
我有以下 ApplicationCable::Connection ruby 文件:
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
我想测试此设置并使用以下 RSpec 测试:
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
it "successfully connects" do
connect "/cable", headers: { "X-USER-ID" => 325 }
expect(connection.user_id).to eq 325
end
end
失败:
Failure/Error: 如果verified_user = env['warden'].user
没有方法错误:
nil:NilClass
的未定义方法“[]”
所以我想删除 env['warden'].user 代码和 return id 325。
我尝试了以下方法:
allow(env['warden']).to receive(:user).and_return(325)
但这产生了以下错误:
undefined local variable or method
env'
我如何测试这个 class?
试试这个:
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 对象是用这个配置初始化的,应该有一个可用的对象(只是当你 运行 你的规格时不需要 - 如上面 link 中所述)。
Rails 5.2 我有以下 ApplicationCable::Connection ruby 文件:
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
我想测试此设置并使用以下 RSpec 测试:
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
it "successfully connects" do
connect "/cable", headers: { "X-USER-ID" => 325 }
expect(connection.user_id).to eq 325
end
end
失败:
Failure/Error: 如果verified_user = env['warden'].user
没有方法错误: nil:NilClass
的未定义方法“[]”所以我想删除 env['warden'].user 代码和 return id 325。 我尝试了以下方法:
allow(env['warden']).to receive(:user).and_return(325)
但这产生了以下错误:
undefined local variable or method
env'
我如何测试这个 class?
试试这个:
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 对象是用这个配置初始化的,应该有一个可用的对象(只是当你 运行 你的规格时不需要 - 如上面 link 中所述)。