如何真正重置单元测试?

发布于 2024-10-28 13:56:34 字数 630 浏览 1 评论 0原文

我想测试类和宝石加载。看看下面这个愚蠢的测试用例:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

段念尘 2024-11-04 13:56:34

创建一个 Test::Unit::TestCase 的子类来在分叉进程中运行测试方法怎么样?

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

如果这可以实现,那么只需更改测试用例的基类即可。

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.

童话 2024-11-04 13:56:34

AFAIK,您无法卸载已加载的文件。您需要为每个测试启动一个单独的 Ruby 进程。 (如果您运行的 Ruby 实现支持同一进程中的多个实例,则可以使用单独的 Ruby 实例。)

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.)

很酷又爱笑 2024-11-04 13:56:34

尝试使用 Kernel#load 和 < code>wrap 设置为 true:

加载(文件名,wrap=false)→ true

加载并执行文件filename中的Ruby程序。如果
文件名未解析为绝对路径,将搜索该文件
for 在 $: 中列出的库目录中。如果可选包装
参数为 true 时,加载的脚本将在
匿名模块,保护调用程序的全局命名空间。
在任何情况下,加载文件中的任何局部变量都不会被修改。
传播到加载环境。

每次您想要对捆绑器进行测试时,请将其加载到一个新的匿名模块中,对该模块内的捆绑器类进行测试,然后继续进行下一个测试。

不过,如果您的代码引用 Bundler 常量,那么您必须设置和取消设置该常量。

我自己没有尝试过,但不明白为什么它不起作用。

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.

春夜浅 2024-11-04 13:56:34

尝试跟踪测试开始之前定义的常量以及测试完成后定义的常量,并删除测试期间定义的常量。

我想这与其说是告诉你如何调用 magic_reset,不如说是告诉你如何实现 magic_reset。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文