How to test monkey patching code?

P

pluskid

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!
 
E

Eivind Eklund

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top