Question

Is it possible to temporarily apply certain methods to a class for tests? I want to be able to run specs depending on many ways to apply it. While I could make a bunch of fixtures with different settings, I find it easier to just class_eval the model in the tests. For example:

describe "some context"
  before do
    Page.class_eval do
      my_applying_method :some => :option
    end
  end

  it "should..."
end

Then in another context block:

describe "another context without the gem applied"
  before do
    Page.class_eval do
      # nothing here since I want to page to be as is
    end
  end

  it "should do something else..."
end

But the problem with the last context block is that it has a modified class (modified in the context block above). Is it possible to reset a class after class_eval? How?

Thanks!

Was it helpful?

Solution

You haven't clarified how you are modifying the class.

The remix library allows you to temporarily include a module and properly uninclude it later.

In general, it's probably safest to just duplicate the class and test the duplicate:

irb(main):001:0> class Foo; end
#=> nil
irb(main):002:0> Foo.dup.class_eval{ @x = 42 }
#=> 42
irb(main):003:0> Foo.class_eval{ @x }
#=> nil

OTHER TIPS

I hope there is a better way to do that but you can use this(and it's with a warning at the Foo = Foo_old line):

module Bar
  def baz
  end
end

class Foo
end

puts Foo.method_defined? :baz #=> false
Foo_old = Foo.dup # create a copy of our class

Foo.class_eval do
  include Bar
end

puts Foo.method_defined? :baz #=> true
Foo = Foo_old
puts Foo.method_defined? :baz #=> false
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top