Search code examples
rubyclass-eval

How do you temporarily "class_eval" for a test?


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!


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