Anonymous, single instance class creation

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

OR:

some_external_object = Object.new
class << some_external_object
def some_method
… do some stuff …
end
end

Is there a way to do that more concisely? Perhaps to eliminate the separate
Object.new?

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.

To explain why I care: I’m finding this technique to be clearer than using
an explicit mocking framework. It tends to help me keep the stubs simple,
and it makes it explicit in the test (or sometimes I pull it out in to
#setup) what’s going on, as opposed to having to look at another class to
see everything that makes the test tick. There are definitely downsides, but
if there are good answers to the two questions above, perhaps not as many as
I thought.

Thanks!

Nathaniel

<:((><

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

OR:

some_external_object = Object.new
class << some_external_object
def some_method
… do some stuff …
end
end

Is there a way to do that more concisely? Perhaps to eliminate the separate
Object.new?

You can encapsulate the method in a Module:

module MyModule
def some_method
… do stuff …
end
end

some_external_object = Object.new
some_external_object.extend MyModule

But I don’t understand why you are creating a new instance of Object and
then extending it. The traditional way to add methods to Object is simply to
create a class containing those methods:

class MyClass # < Object [implied]
def some_method
… do stuff …
end
end

some_thing = MyClass.new # = Object.new plus the methods in MyClass

You say you do this in tests a lot (test/unit?) Can you give a more concrete
example? I can’t see why

class MyTest < Test::Unit::TestCase
def some_method

end
… rest of tests
end

doesn’t do the business. The test framework will generate an instance of
MyTest in order to run it, and therefore this instance will have
some_method available.

Otherwise, you define another class Foo, and in your initialize method
create an instance of it:

def initialize
@some_external_object = Foo.new
end

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.

Again, I’d like to see the code which makes use of the above pattern. Are
you using local variables inside a class but outside a method??

class MyTest < Test::Unit::TestCase
a = “stuff”
def some_method
a # ??
end
end

because if so, maybe you just want

class MyTest < Test::Unit::TestCase
def initialize
@a = “stuff”
end
def some_method
@a
end
end

You can achieve what you want, though, using define_method which converts
a proc object into a method. The example at the bottom of

might help.

I also valuely remember that 1.8 might let you pass a block to ‘def’.

Regards,

Brian.

···

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?

You say you do this in tests a lot (test/unit?)

But of course :wink:

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

<:((><

···

Brian Candler [mailto:B.Candler@pobox.com] wrote:

On Sat, Aug 02, 2003 at 06:13:55PM +0900, Nathaniel Talbott wrote:

I was hallucinating, it’s Class.new which can take a block. But it looks
like this gives a funky new syntax:

Foo = Class.new {
define_method(:bar) {
puts “Hello world”
}
}
Foo.new.bar

Regards,

Brian.

···

On Sat, Aug 02, 2003 at 10:03:09PM +0900, Nathaniel Talbott wrote:

I also valuely remember that 1.8 might let you pass a block to ‘def’.

Really? I don’t remember that…

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 = Mockobj.new
 m.a = {"one"=>1}
 .. do stuff
 m.a = {"two"=>2}
 .. 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.

tu2.rb (534 Bytes)

···

On Sat, Aug 02, 2003 at 10:03:09PM +0900, Nathaniel Talbott wrote:

I guess this isn’t more concise, but I use something like this:

require ‘test/unit’
require ‘test/unit/mock’

class TC_ParamPrettifier < Test::Unit::TestCase
def setup
@cgi = Test::Unit::MockObject( CGI ).new
end

 def test_prettify
   @cgi.setReturnValues( :params =>
     [{'param1' => 'value1', 'param2' => 'value2'}] )
 assert_equal((<<EXP).chomp, ParamPrettifier.new(cgi).prettify)

param1
value1
param2
value2
EXP
end
end

Thanks for all your hard work on Test::Unit, BTW. =:)

···

On Saturday, Aug 2, 2003, at 07:03 America/Denver, Nathaniel Talbott wrote:

require ‘test/unit’

class TC_ParamPrettifier < Test::Unit::TestCase
def test_prettify
cgi = Object.new
def cgi.params
{‘param1’ => ‘value1’, ‘param2’ => ‘value2’}
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.


Michael Granger ged@FaerieMUD.org
Rubymage, Believer, Architect
The FaerieMUD Consortium http://www.FaerieMUD.org/

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.

Oh, I’ve created that class many times in the past… but I guess after
doing lots and lots of unit testing (and I have done LOTS and LOTS of unit
testing) I’ve come to find that, for me at least, it’s often more useful to
start (and sometimes end) with a completely self-contained test method. Why?
Hmmm…

Well, for one, it cuts down on start-up overhead. I like to write a little
test, watch it fail, write a little code, watch it pass, write a little
test, ad infinitum. If my test method is self-contained when I start, I
don’t have to spend precious brain cycles (and when you’re working in 60-300
second cycles, seconds are important) figuring out what the name of the Mock
class should be, if it needs an initializer, where it should go, etc. I just
create an object, attach some methods, and pass it in. Easy, quick, concise,
to the point.

Another thing that factors in here is the issue of reuse in tests. I don’t
aggressively remove duplication in tests like I do in code. My tests help
document the behavior of the system, and I want those tests to say a lot.
Too much reuse cuts down on how much an individual tests says. I have to
look here and find this mock object, and and here to find that one, and in
setup to see how they’re initialized, etc. Instead I often find it’s better
to keep my test methods small and decoupled, with each saying just what
needs to be said for that particular test - even if some of what they say
overlaps what another test says.

Plus, I just think it’s nifty… I can show it to all my friends stuck in
Java land and say, “Can’t do that in Java, can ya?” :slight_smile:

Now, I certainly pull things out in to setup, create classes just for
testing, and do various other types of reuse in my tests. Sometimes I wonder
if that means my tests (or the units they’re testing) are too complex. Other
times I know that that complexity is necessary.

Anyhow, I don’t think you’ll convince me to stop doing this - and I’d
encourage you (and anyone else) to try it and see what it does to your
testing. There’s an equilibrium between reuse in tests and expressing
everything in the test method. I’m sure that the right decision is different
for every test we write.

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.

That’s not why I want to do it, though; I find that a lot of times when I
have some values returned by a mock, I want to use those values in my
assertions on the class under test. So if I can bind closures as the methods
for my inline mock, I don’t have to declare those values twice, or add a
mechanism to pass them in to the mock.

Thanks for your help,

Nathaniel

<:((><

···

Brian Candler [mailto:B.Candler@pobox.com] wrote: