# Properly extending test::unit to add logging

**URL:** <https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727>\
**Category:** Ruby\
**Created:** [June 7, 2006, 5:30pm UTC](https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727 "2006-06-07T17:30:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![rsanheim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@rsanheim](https://www.ruby-forum.com/u/rsanheim)\
**Post date:** [June 7, 2006, 5:30pm UTC](https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727/1 "2006-06-07T17:30:49Z")

</div>

Hi,

I’d like to open up test::unit to add default logging to setup and  
teardown. In java I did this with a base test class that every other  
test extended, but that was never very nice as you had to remember to  
call super in subclasses. The other option was adding aspects and all  
that complexity. So I thought I could do it nicer in ruby with the  
following:

alias\_method :old\_setup, :setup  
def setup  
logger.debug “\*\*\*\* Beginning setup for: #{name} \*\*\*\*”  
old\_setup  
end

Is this the proper way to extend builtin methods, and still preserve  
the old behavior? I’m thinking the timing that the above code gets  
called is important. Right now I’m getting one test error when I  
extend setup as above, as opposed to leaving it out, so I must be dong  
something wrong.

Btw - this w/i a Rails app (the above code is w/i test\_helper), but I  
figured this is more ruby then rails specific.

thanks,  
Rob

---

<div class="post-metadata">

**Author:** ![rsanheim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@rsanheim](https://www.ruby-forum.com/u/rsanheim)\
**Post date:** [June 7, 2006, 5:33pm UTC](https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727/2 "2006-06-07T17:33:56Z")

</div>

On Thu, 8 Jun 2006, Rob S. wrote:

> def setup  
> logger.debug “\*\*\*\* Beginning setup for: #{name} \*\*\*\*”  
> old\_setup  
> end

whenever you wrap methods like this **always** , **always** , **always**  
do this

alias\_method “old\_method”, “method”

def method \*a, &b  
# …  
old\_method \*a, &b  
# …  
end

you need to collect any args and block and pass them through.

regards.

-a

---

<div class="post-metadata">

**Author:** ![rsanheim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@rsanheim](https://www.ruby-forum.com/u/rsanheim)\
**Post date:** [June 8, 2006, 1:16am UTC](https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727/3 "2006-06-08T01:16:30Z")

</div>

On 6/7/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> you need to collect any args and block and pass them through.
> 
> regards.

Thanks for the tip. Besides that, are there any other gotchas related  
to redefining methods? For instance, I’m redefining my\_foo inside  
module x, but y and z call my\_foo before module x ever needs to get  
loaded. Does that mean that my\_foo will be the old version for y and  
z, then the new version for any callers after module x gets loaded?

- rob

---

<div class="post-metadata">

**Author:** ![rsanheim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@rsanheim](https://www.ruby-forum.com/u/rsanheim)\
**Post date:** [June 8, 2006, 1:38am UTC](https://www.ruby-forum.com/t/properly-extending-test-unit-to-add-logging/62727/4 "2006-06-08T01:38:16Z")

</div>

On Thu, Jun 08, 2006 at 08:15:21AM +0900, Rob S. wrote:

> > end
> > 
> > you need to collect any args and block and pass them through.
> > 
> > regards.
> 
> Thanks for the tip. Besides that, are there any other gotchas related  
> to redefining methods?

This one is at least as conspicuous as the above one, but just in  
case…

Try to come up with a more imaginative name than old\_method for the old  
definition, or you’ll get SystemStackErrors when somebody also overrides  
it  
using the same name…

If the method doesn’t take a block (or you’re running 1.9), you can also  
use  
the following idiom:

old\_meth = instance\_method(:method)  
define\_method(:method) do |\*a| # &b too on 1.9

# …

old\_meth.bind(self).call(\*a) # ditto

# …

end

which is safer name-clash-wise, but note that this is slower than the  
alias\_method mechanism.

> For instance, I’m redefining my\_foo inside  
> module x, but y and z call my\_foo before module x ever needs to get  
> loaded. Does that mean that my\_foo will be the old version for y and  
> z, then the new version for any callers after module x gets loaded?

Yes (if the later calls would see the new definition at all under the  
standard  
method resolution rules).
