[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to test monkey patching code?

Chiyuan Zhang

2/7/2008 1:58:00 PM

Hi, all!

I'm wondering how to test some monkey patching code. Take the standard
library 'jcode'
in Ruby 1.8 for example. It do some monkey patching for the core
String class when I
require it. If I want to write some unit-test or spec for it, how to
avoid it from affecting other
tests? In other words, how can I "uninstall" those monkey patching
after the test case
is finished or how can I constrain the monkey patching inside a ...,
say, namespace?

I tried the following code:


orig_string = Object::String.clone

$KCODE = 'u'
require 'jcode'

# do testings

Object::String = orig_string

str1 = "foo"
str2 = String.new("foo")

# jlength are monkey patching
puts str1.jlength # => 3
puts str2.jlength # => raise NoMethodError


As I expected, str2.jlength raises NoMethodError, but str1 which is
built
by a string literal, returned 3, still being patched.

Further more, when I type those code directly in IRB, the irb fire out
some exception and exited immediately:

C:/ruby/lib/ruby/1.8/irb/ruby-token.rb:101:in `Token': undefined
method `ancesto
rs' for "=":String (NoMethodError)
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:400:in `lex_init'
from C:/ruby/lib/ruby/1.8/irb/slex.rb:237:in `call'
from C:/ruby/lib/ruby/1.8/irb/slex.rb:237:in `match_io'
from C:/ruby/lib/ruby/1.8/irb/slex.rb:222:in `match_io'
from C:/ruby/lib/ruby/1.8/irb/slex.rb:76:in `match'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:287:in `token'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:263:in `lex'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:234:in
`each_top_level_stateme
nt'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:in
`each_top_level_stateme
nt'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:in
`each_top_level_stateme
nt'
from C:/ruby/lib/ruby/1.8/irb.rb:146:in `eval_input'
from C:/ruby/lib/ruby/1.8/irb.rb:70:in `start'
from C:/ruby/lib/ruby/1.8/irb.rb:69:in `catch'
from C:/ruby/lib/ruby/1.8/irb.rb:69:in `start'
from C:/ruby/bin/irb:13

I suppose IRB itself is doing some monkey patching to String? So, is
there any
way to ..., return to my original question, to test monkey patching
code?

Thanks!
1 Answer

Eivind Eklund

2/7/2008 2:26:00 PM

0

On Feb 7, 2008 2:59 PM, pluskid <pluskid@gmail.com> wrote:
> Hi, all!
>
> I'm wondering how to test some monkey patching code. Take the standard
> library 'jcode'
> in Ruby 1.8 for example. It do some monkey patching for the core
> String class when I
> require it. If I want to write some unit-test or spec for it, how to
> avoid it from affecting other
> tests? In other words, how can I "uninstall" those monkey patching
> after the test case
> is finished or how can I constrain the monkey patching inside a ...,
> say, namespace?
>
> I tried the following code:
>
>
> orig_string = Object::String.clone
>
> $KCODE = 'u'
> require 'jcode'
>
> # do testings
>
> Object::String = orig_string


I would try

orig_string = Object::String
Object::String = Object::String.clone

require 'jcode'

# do testings

Object::String = orig_string

instead.

Ie, let the modifications happen to a clone, rather than the original.
That might stop "" from generating a monkey-patched string during
testing, though.

Eivind.