开发者

How to really reset a unit test?

开发者 https://www.devze.com 2023-02-21 04:04 出处:网络
I\'d like to test class and gem loading. Have a look at the following stupid test case: require \'rubygems\'

I'd like to test class and gem loading. Have a look at the following stupid test case:

require 'rubygems'
require 'shoulda'

class SimpleTest < Test::Unit::TestCase

    context 'This test' do

       should 'first load something' do
           require 'bundler'

           assert Object.const_defined? :Bundler
       end

       should 'second have it reset again' do
           assert !Object.const_defined?(:Bundler)
       end

       teardown do
         # This works, but is tedious and unclean
         #Object.send :remove_const, :Bundler rescue nil

         # Instead I want something like this ;)
         开发者_如何学编程magic_reset
       end

    end

end


How about creating a subclass of Test::Unit::TestCase which runs the test method in a forked process?

class ForkingTestCase < Test::Unit::TestCase
  def run(...)
    fork do
      super.run(...)

      # somehow communicate the result back to the parent process
      # this is the hard part
    end
  end  
end

If this can be implemented, it should then just be a matter of changing the base class of your test case.


AFAIK, you cannot unload a file that you have loaded. You need to start a separate Ruby process for every test. (Or a separate Ruby instance if you are running on a Ruby implementation which supports multiple instances in the same process.)


Try using Kernel#load with wrap set to true:

load(filename, wrap=false) → true

Loads and executes the Ruby program in the file filename. If the filename does not resolve to an absolute path, the file is searched for in the library directories listed in $:. If the optional wrap parameter is true, the loaded script will be executed under an anonymous module, protecting the calling program’s global namespace. In no circumstance will any local variables in the loaded file be propagated to the loading environment.

each time you want to do a test of bundler, load it into a new anonymous module, do your tests on the bundler class within that module, and then go onto your next test.

If your code refers to the Bundler constant, then you'd have to set and unset that constant, though.

I haven't tried it myself, but can't see why it wouldn't work.


Try keeping track of what constants were defined before your tests started, and what constants are defined after your test finished, and remove the constants that were defined during the test.

I guess this isn't so much telling you how to call magic_reset as how to implement magic_reset.

0

精彩评论

暂无评论...
验证码 换一张
取 消