Fernando G. wrote:
Is this possible?.. am I completely lost?.. is there any better way to
do this?
I’d suggest you use an existing mocking library like “mocha”. Example:
-------- 8< ----------------
require ‘net/pop’
require ‘test/unit’
require ‘rubygems’
require ‘mocha’
code to test
class Foo
attr_reader :opts
def initialize(opts)
@opts = opts
end
def bar(block)
Net::POP3.start( opts[:server], opts[:port], opts[:user],
opts[:pass] ) do |pop|
pop.each_mail do |m|
block.call( m )
end
end
end
end
tests
class MyTest < Test::Unit::TestCase
def test_1
mails = [“xxxxx”,“yyy”]
mockpop = mock
mockpop.expects(:each_mail).multiple_yields(*mails)
Net::POP3.expects(:start).with(“127.0.0.1”, 110, “a”,
“b”).yields(mockpop)
foo = Foo.new(:server=>"127.0.0.1", :port=>110, :user=>"a",
:pass=>“b”)
res = []
foo.bar(lambda { |x| res << x.size })
assert_equal [5,3], res
end
more expectation-based style
def test_2
mails = [“xxxxx”,“yyy”]
mockpop = mock
mockpop.expects(:each_mail).multiple_yields(*mails)
Net::POP3.expects(:start).with(“127.0.0.1”, 110, “a”,
“b”).yields(mockpop)
mockblock = mock
seq = sequence(:block)
mockblock.expects(:call).with(mails[0]).in_sequence(seq)
mockblock.expects(:call).with(mails[1]).in_sequence(seq)
foo = Foo.new(:server=>"127.0.0.1", :port=>110, :user=>"a",
:pass=>“b”)
foo.bar(mockblock)
end
end
-------- 8< ----------------
I find there’s something unsatisfying about tests which look like this.
Sometimes you can spend more effort on the mechanics of mocking than on
solving the original problem, and the resulting tests are closely
coupled to the internal implementation of your function. But that is
what you asked for
Refactoring might make your code easier to test. e.g.
-------- 8< ----------------
require ‘net/pop’
require ‘test/unit’
require ‘rubygems’
require ‘mocha’
class Foo
attr_reader :opts
def initialize(opts)
@opts = opts
end
def bar(block)
for_all_messages do |m|
block.call(m)
end
end
private
def for_all_messages(&blk)
Net::POP3.start( opts[:server], opts[:port], opts[:user],
opts[:pass] ) do |pop|
pop.each_mail(&blk)
end
end
end
class MyTest < Test::Unit::TestCase
def test_1
foo = Foo.new({})
mails = ["xxxxx","yyy"]
foo.expects(:for_all_messages).multiple_yields(*mails)
res = []
foo.bar(lambda { |x| res << x.size })
assert_equal [5,3], res
end
end
-------- 8< ----------------
HTH,
Brian.