我正在使用Factory Girl生成测试日期以模拟与ldap服务器的连接(因为我不希望应用程序每次都能建立真正的ldap连接以便成功运行我的测试)。 / p>
我想模仿此连接并确认这是成功发生的。
我的工厂女孩数据是:
/factories/connections.rb
FactoryGirl.define do
factory :connection do
host "just-ln1-wdc03.company.qube"
port 389
base "DC=company,DC=qube"
username "cat@company.qube"
password "cats123"
end
end
我的Rspec测试是:
authenticate_spec.rb
require 'spec_helper'
describe "#is_authenticated_by_ldap" do
let(:connection) {FactoryGirl.build(:connection)}
it "queries ldap server and returns success" do
allow(:connection).to receive(:is_authenticated_by_ldap).with("cat@company.qube", "cats123").and_return(true)
end
end
spec_helper.rb
require 'factory_girl'
require_relative './factories/connections.rb'
RSpec.configure do|config|
...
authenticate.rb
def is_authenticated_by_ldap(credentials)
full_username = credentials[0] + EXTENSION #EXTENSION = "company.com"
ldap = Net::LDAP.new :host => "just-ln1-wdc03.company.qube", # your LDAP host name or IP goes here,
:port => 389, # your LDAP host port goes here,
# :encryption => :simple_tls,
:base => "DC=company,DC=qube", # the base of your AD tree goes here,
:auth => {
:method => :simple,
:username => full_username, # a user w/sufficient privileges to read from AD goes here,
:password => credentials[1] # the user's password goes here
}
is_authorized = ldap.bind
return is_authorized
end
传递给is_authenticated_by_ldap
方法的参数本质上分别是用户名和密码凭证[0]和凭证[1]。
当我运行此rspec spec/authenticate_spec.rb
时,收到以下错误:
Authenticate
←[32m authenticates a user on qube server←[0m
#is_authenticated_by_ldap
←[31m queries ldap server and returns success (FAILED - 1)←[0m
Failures:
1) Authenticate#is_authenticated_by_ldap queries ldap server and returns success
←[31mFailure/Error: allow(:connection).to receive(:is_authenticated_by_ldap).with("cats@company.qube", "cats123").and_return(true)←[0m
←[31mTypeError:←[0m
←[31m can't define singleton←[0m
我相信我已回答了我自己的问题并在此处发布了解释,因为其他人可能会遇到此问题,并寻求像我一样的解决方案:
RSpec 3.0有一个称为实例double的特性,它将类名或对象作为它的第一个参数,然后验证任何被存根的方法是否存在并在该类的实例上执行。
所以在我的情况下,因为我有一个处理我的身份验证功能的Authenticate模块,我在我的Rspec测试中创建了一个虚拟类,其中还包含了所述模块。(参见下面的代码)
要求'spec_helper'
class Dummy
include Authenticate
end
describe Authenticate do
let(:dummy_class) {Dummy.new.authenticate}
let(:credentials) {FactoryGirl.build_stubbed(:credentials)}
it "authenticates a user on qube server" do
expect(:dummy_class).to be
end
describe "#is_authenticated_by_ldap" do
it "queries ldap server and returns successful connection" do
dummy = instance_double("Dummy")
allow(dummy).to receive(:is_authenticated_by_ldap).with(:credentials).and_return(true)
expect(dummy.is_authenticated_by_ldap(:credentials)).to be(true)
end
end
end
#spec/factories/credentials.rb
FactoryGirl.define do
factory :credentials do
username "cats@company.com"
password "cats123"
end
end
并使用factory_girl(用户名和密码)定义测试数据作为is_authenticated_by_ldap方法的参数传递(此方法确认是否成功连接到ldap服务器)。使用RSpec 3.0语法,如果使用存根/模拟,带有接收匹配器的allow方法告诉假对象返回一个值以响应给定的消息/方法。在我的情况下,我希望测试通过(成功的ldap连接)或失败(不成功的ldap连接)。为了确认我的模拟工作正常并且不是误报,使用了工厂女孩gem(并且不存在于ldap服务器上)定义的测试数据并且测试通过了。我还注释掉了该方法的源代码并重新进行了测试,并且按预期失败了。