Stubbing /mocking ldap within a method

given I have the following with the internal assignments to filter and
ldap:

class Collaborator
def self.search_ldap(term)
last_name = term.strip.split(/[, ]/).first.downcase
filter = Net::LDAP::Filter.eq(‘surName’, last_name)
ldap = Net::LDAP.new( :host => ‘foo’, :port => 636, :base => ‘bar’,
:encryption => :fiz)
ldap.search(:filter => filter)
end
end

I would like mock out the LDAP class so i can test the behavior of the
method without LDAP.

describe Collaborator do
it “should search ldap and return last names from the first item of
the
search phrase” do
entry = Net::LDAP::Entry
items = {:cn=>[“Jim B.”],:uid=>[‘bob46’],:mail=>‘[email protected]’}
items.each{|k,v| entry.stub(k) {v} }

# how do I get to objects inside this method, something like?
assigns(:ldap).stub(:search).and_return(entry) # but that doesnt 

work
Collaborator.search_ldap(“Bob”).should == [entry]
end
end

On Tue, Jun 21, 2011 at 17:00, Jed S. [email protected]
wrote:

I would like mock out the LDAP class so i can test the behavior of the
method without LDAP.

In this case, I’d invoke the rule “Don’t mock types you don’t own”.

What can you trust? LDAP does the right thing.
What can you get wrong? Sending the wrong parameters to LDAP.
Therefore, check the parameters you send to LDAP.

class Collaborator
def initialize(ldapGateway = LdapGateway.new)
@gateway = ldapGateway
end

def self.search_ldap(term)
last_name = term.strip.split(/[, ]/).first.downcase
@gateway.search(‘surName’, last_name, ‘foo’, 636, ‘bar’, :fiz)
end
end

class LdapGateway
def search(label, value, host, port, base, encryption)
filter = Net::LDAP::Filter.eq(‘surName’, last_name)
ldap = Net::LDAP.new( :host => ‘foo’, :port => 636, :base =>
‘bar’, :encryption => :fiz)
ldap.search(:filter => filter)
end
end

Judging only by the names, “label” and “value” seem separate from
“host”“encryption”. My intuition tells me to move the latter group
into constructor parameters.

class Collaborator
def initialize(ldapGateway)
@gateway = ldapGateway
end

def self.search_ldap(term)
last_name = term.strip.split(/[, ]/).first.downcase
@gateway.search(‘surName’, last_name)
end
end

class LdapGateway
def initialize(host, post, base, encryption)
# assign to fields
end

def search(label, value)
filter = Net::LDAP::Filter.eq(‘surName’, last_name)
# SMELL Temporal duplication; can we create an LDAP in the
constructor?
ldap = Net::LDAP.new( :host => @host, :port => @port, :base =>
@base, :encryption => @encryption)
ldap.search(:filter => filter)
end
end

Now the LdapGateway responds to search(label, value), so I don’t think
Collaborator needs to know that any LDAP is going on.

class Collaborator
def initialize(term_repository)
@term_repository = term_repository
end

def self.search_ldap(term)
last_name = term.strip.split(/[, ]/).first.downcase
@term_repository.search(‘surName’, last_name)
end
end

I’m using the mechanical name “Repository” here, because I don’t yet
understand the role this object plays in the system.

class LdapGateway # I’m a TermRepository! Extract a module someday?
def initialize(host, post, base, encryption)
# assign to fields
end

def search(label, value)
filter = Net::LDAP::Filter.eq(‘surName’, last_name)
# SMELL Temporal duplication; can we create an LDAP in the
constructor?
ldap = Net::LDAP.new( :host => @host, :port => @port, :base =>
@base, :encryption => @encryption)
ldap.search(:filter => filter)
end
end

Now it’s easy to check:

describe Collaborator do
context “when searching” do
it “should pass the proper surname to the TermRepository” do
termRepository = mock(“a TermRepository”)
termRepository.should_receive(:search).with(‘surName’,
‘rainsberger’)

  Collaborator.new(termRepository).search('J. B. Rainsberger')
end

it "should return the repository's results" do
  Collaborator.new(stub(:search => ["a", "b", "c"])).search('J. B.

Rainsberger’).should == [“a”, “b”, “c”]
end
end
end

Does that help you?

J. B. (Joe) Rainsberger :: http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Author, JUnit Recipes
Free Your Mind to Do Great Work ::
http://www.freeyourmind-dogreatwork.com