--0OAP2g/MAC+5xKAE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sat, Aug 02, 2003 at 10:03:09PM +0900, Nathaniel Talbott wrote:
> > Can you give a more concrete example?

... snip example ...

> 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.

I'd just create a class - see attached minor modification to your example.
It might not be any more concise but IMO it's very clear (clearer than
attaching methods to a vanilla Object anyway), very flexible as you can
expand the capabilities of the mock object easily, and perhaps most
important, easily reusable as you add extra test methods.

> 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 pass in stuff to initialize of course, and accessors to reset the
object's "private" state seem reasonable enough to me.

If you are setting up local variables, binding them into closures and then
binding those closures to objects as method definitions, then really those
local variables are only there to preserve state between calls of a method.
In that case all you've done is simulate an object's instance variables.

You *can* write ruby programs without instance variables at all - see
http://ruby-talk.org/63649 - but why go to that trouble?

I guess when you write:

     m  ockobj.new
     m.a  "one"}
     .. do stuff
     m.a  "two"}
     .. do stuff

then there's an extra 'm.' in front of each assignment, compared to your
approach of using local variables. But I still reckon it's worth it for
clarity and reusability.

Regards,

Brian.

--0OAP2g/MAC+5xKAE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="tu2.rb"

require 'test/unit'

class MockCGI
  attr_accessor :params
end

class TC_ParamPrettifier < Test::Unit::TestCase
  def test_prettify
    cgi  ockCGI.new
    cgi.params  'param1' 'value1', 'param2' 'value2'}
    
    assert_equal((<<EXP).chomp, ParamPrettifier.new(cgi).prettify)
param1
  value1
param2
  value2
EXP
  end
end

class ParamPrettifier #Contrived, I know
  def initialize(cgi)
    @cgi  gi
  end
  
  def prettify
    @cgi.params.collect do |key, value|
      "#{key}\n  #{value}"
    end.join("\n")
  end
end


--0OAP2g/MAC+5xKAE--