将RSpec与Factory Girl一起使用并获得一个无法定义单例错误

时间:2015-01-07 13:37:07

标签: ruby rspec mocking factory-bot

我正在使用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测试中创建了一个虚拟类,其中还包含了所述模块。(参见下面的代码)

authenticate_spec.rb

要求'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服务器上)定义的测试数据并且测试通过了。我还注释掉了该方法的源代码并重新进行了测试,并且按预期失败了。

0 个答案:

没有答案