如何在带有rspec的钩子中使用Dir.mktmpdir?

时间:2011-08-02 18:43:30

标签: ruby rspec hook block

我想在before-each钩子中创建一个tmpdir,并在rspec示例中使用它的路径。我想使用Dir.mktmpdir的块形式,因此在示例结尾处删除了dir。

问题:

  • 我不能让块在前挂钩中退出,或者在我的示例运行之前删除目录。
  • 我无法在我的例子中包裹一个块。我尝试过使用一下 钩子,但不与实例共享实例变量( doc确认了此行为。)

目前我正在使用延续(如果我在1.9上,光纤会更好)跳出块,然后跳回来让mktmpdir可以清理。

有没有更简单的方法来实现这一点,而不是在每个示例中移动mktmpdir?确实,我可以在后挂钩中删除目录,但我也在寻找这种类型问题的一般解决方案 - 我不总是知道当块退出时应该运行什么清理代码。

仅供参考,我的延续代码,封装在一个类中:

class SuspendableBlock
  def initialize
  end

  def run(&block)
    raise LocalJumpError unless block_given?
    callcc {|@run_cc|
      yield
      @resume_cc.call if @resume_cc
    }
    nil
  end

  # saves the suspend point & causes run to return immediately
  def suspend
    raise "run must be called first" unless @run_cc
    callcc {|@suspend_cc|
      @run_cc.call(@suspend_cc)
    }
    nil
  end

  # jumps back to after the suspend point to finish the block.
  # after the block exits, return immediately from resume.
  def resume
    raise "suspend must be called first" unless @suspend_cc
    callcc {|@resume_cc|
      @suspend_cc.call(@resume_cc)
    }
    nil
  end
end

用法:

before :each do
  @sb = SuspendableBlock.new
  @sb.run do
    Dir.mktmpdir do |dir|
      @tmpdir_path = Pathname.new(dir)
      @sb.suspend
    end
  end
end

after :each do
  @sb.resume
end

it "should use a tmp dir" do
  p @tmpdir_path
end

1 个答案:

答案 0 :(得分:1)

根据我的阅读(从未测试过),延续效率非常低。

虽然我无法帮助你继续,但你可以使用Thread来模仿Fibers:https://github.com/tmm1/fiber18

已经完成的一个库是em-spec(https://github.com/tmm1/em-spec),每个测试都在光纤中运行,您可以根据自己的需要对其进行修改。