Brian Candler [mailto:B.Candler / pobox.com] wrote: > On Sat, Aug 02, 2003 at 06:13:55PM +0900, Nathaniel Talbott wrote: > > I find myself doing the following in tests a lot: > > > > some_external_object = Object.new > > def some_external_object.some_method > > ... do some stuff ... > > end > > > > Is there a way to do that more concisely? Perhaps to eliminate the > > separate Object.new? <snip> > You say you do this in tests a lot (test/unit?) But of course ;-) > Can you give a more concrete example? require 'test/unit' class TC_ParamPrettifier < Test::Unit::TestCase def test_prettify cgi = Object.new def cgi.params {'param1' => 'value1', 'param2' => 'value2'} end assert_equal((<<EXP).chomp, ParamPrettifier.new(cgi).prettify) param1 value1 param2 value2 EXP end end class ParamPrettifier #Contrived, I know def initialize(cgi) @cgi = cgi end def prettify @cgi.params.collect do |key, value| "#{key}\n #{value}" end.join("\n") end end The basic idea is that I have a class (like CGI) that's a pain to set up and/or use, and I want to mock (sham, fake, stub) it. So I create a regular old object (ROO... MOO? FOO? GOO? Sorry...) and take advantage of Ruby's wonderful dynamic nature to just add the methods that I need for that test. I'm just looking for ways to make it easier and/or more concise to do this. > > Also, is there a way to let the methods be more like closures, i.e.: > > > > a = "stuff" > > > > some_external_object = Object.new > > def some_external_object.some_method > > a #from external scope > > end > > > > assert_equal(a, method_under_test(some_external_object)) > > > > That would make it even more powerful. > > If you find yourself needing that, usually the 'right' > solution is to make 'a' into an instance variable (@a) of some object. If you take my example above and imagine that you want to define and use the hash returned by the mock CGI object in the test method as well, you can see why this is advantageous. What I've done in the past is to add an accessor method for such data, but I'm looking for something more concise. > You *can* achieve what you want, though, using define_method > which converts a proc object into a method. The example at > the bottom of http://www.rubygarden.org/ruby?SingletonTutorial > might help. Ah! This does exactly what I want... I'll have to grab that method, stick it in a module, and include it in my tests. Thanks for the pointer. > I also valuely remember that 1.8 might let you pass a block to 'def'. Really? I don't remember that... Thanks, Nathaniel <:((><