# Dynamically add a method to a TestCase

**URL:** <https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806>\
**Category:** Ruby\
**Created:** [January 2, 2008, 7:55pm UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806 "2008-01-02T19:55:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![commander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@commander](https://www.ruby-forum.com/u/commander)\
**Post date:** [January 2, 2008, 7:55pm UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806/1 "2008-01-02T19:55:49Z")

</div>

Hi,

I’m experimenting with the dynamic features of ruby to add methods to  
a TestCase. Here is my test script:

require ‘watir’  
require ‘test/unit’

class MyTest \< Test::Unit::TestCase  
end

for num in [“a”,“b”,“c”]  
MyTest.send(:define\_method,“test\_” + num) {  
assert(false,"-\>"+num)  
}  
end

It works fine so far, but all asserts display “-\>c” as error message.  
I don’t understand why! Any hint? How to fix it?

regards,  
Achim

---

<div class="post-metadata">

**Author:** ![commander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@commander](https://www.ruby-forum.com/u/commander)\
**Post date:** [January 2, 2008, 8:07pm UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806/2 "2008-01-02T20:07:34Z")

</div>

On Jan 2, 2008 1:55 PM, Achim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Achim

That’s exactly what you’re telling assert to do. Method definition is  
something like:

assert(expression, error\_message = nil)

What exactly are you wanting to do?

Jason

---

<div class="post-metadata">

**Author:** ![commander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@commander](https://www.ruby-forum.com/u/commander)\
**Post date:** [January 2, 2008, 8:09pm UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806/3 "2008-01-02T20:09:20Z")

</div>

On Jan 2, 2008 2:06 PM, Jason R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > class MyTest \< Test::Unit::TestCase
> 
> Jason

Dah crap, excuse my previous email. I need to work on my reading  
comprehension.

That is odd. I would assume that a puts there would always say “c”,  
though  
it can’t hurt to try.

Jason

---

<div class="post-metadata">

**Author:** ![commander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@commander](https://www.ruby-forum.com/u/commander)\
**Post date:** [January 3, 2008, 3:53am UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806/4 "2008-01-03T03:53:56Z")

</div>

On Jan 2, 2008, at 1:55 PM, Achim D. wrote:

> for num in [“a”,“b”,“c”]  
> MyTest.send(:define\_method,“test\_” + num) {  
> assert(false,"-\>"+num)  
> }  
> end
> 
> It works fine so far, but all asserts display “-\>c” as error message.  
> I don’t understand why! Any hint? How to fix it?

One way to fix it is to use eval rather then send:

`
require 'test/unit'
class MyTest < Test::Unit::TestCase
for ch in %w[a b c]
eval %[define_method(“test_#{ch}”) { assert(false, “->#{ch}”) }]
end
end
`

Regards, Morton

---

<div class="post-metadata">

**Author:** ![commander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@commander](https://www.ruby-forum.com/u/commander)\
**Post date:** [January 2, 2008, 8:22pm UTC](https://www.ruby-forum.com/t/dynamically-add-a-method-to-a-testcase/124806/5 "2008-01-02T20:22:12Z")

</div>

Achim D. wrote:

> for num in [“a”,“b”,“c”]  
> MyTest.send(:define\_method,“test\_” + num) {  
> assert(false,"-\>"+num)  
> }  
> end
> 
> It works fine so far, but all asserts display “-\>c” as error message.  
> I don’t understand why! Any hint? How to fix it?

It’s the way the ‘for’ construct scopes the ‘num’ variable. All three  
method definition blocks are seeing ‘num’ in the same scope, so they all  
get the last assigned value, “c”.

Try this:

procs = []  
for num in [“a”,“b”,“c”]  
#[“a”,“b”,“c”].each do |num|  
procs \<\< proc {  
num  
}  
end

procs.each do |pr|  
puts pr.call  
end

That prints three 'c’s.

Now uncomment the ‘each’ line and comment out the ‘for’ line, and you’ll  
see the scope difference!
