Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 带螺纹的Rspec_Ruby_Multithreading_Rspec - Fatal编程技术网

Ruby 带螺纹的Rspec

Ruby 带螺纹的Rspec,ruby,multithreading,rspec,Ruby,Multithreading,Rspec,我有一个在初始化时启动线程的类,我可以从公共方法推送该线程中的一些操作: class Engine def initialize @actions = [] self.start_thread() end def push_action(action) start = @actions.empty? @actions.push(action) if start @thread.run end end prote

我有一个在初始化时启动线程的类,我可以从公共方法推送该线程中的一些操作:

class Engine

  def initialize
    @actions = []
    self.start_thread()
  end

  def push_action(action)
    start = @actions.empty?
    @actions.push(action)
    if start
      @thread.run
    end
  end

  protected

  def start_thread
    @thread = Thread.new do
      loop do

        if @actions.empty?
          Thread.stop
        end

        @actions.each do |act|
          # [...]
        end
        @actions.clear
        sleep 1
      end
    end
  end
end
我想用RSpec测试这个类,以检查当我通过一些操作时会发生什么。但我不知道怎么做


提前感谢

好的,我找到了一个解决方案,但它很脏:

describe Engine do

  describe "#push_action play" do

    it "should do the play action" do
      # Construct the Engine with a mock thread
      mock_thread = double("Useless Thread")
      allow(mock_thread).to receive(:run)
      expect(Thread).to receive(:new).and_return(mock_thread)
      engine = Engine.new

      allow(engine).to receive(:sleep)

      # Expect that the actual play action will be processed
      expect(engine).to receive(:play)

      # push the action in the actions' list
      engine.push_action(:play)

      # Stop the thread loop when the stop() method is called
      expect(Thread).to receive(:stop).and_raise(StandardError)


      # Manually call again the start_thread() protected method with a yielded thread
      # in order to process the action
      expect(Thread).to receive(:new).and_yield
      expect {engine.send(:start_thread)}.to raise_error(StandardError)  
    end

  end
end

如果有人有更好的解决方案,我会非常高兴:)

谢谢@Mark,但我不使用rails。这不是rspec,但Mike Perham写的一篇非常好的文章是一个好方法->感谢链接,这是一篇非常有趣的阅读。但有件事困扰着我:“我公开了它的内部API,这样测试套件就可以完全访问这些方法”。我知道这会使测试更容易编写,但这是一个好主意吗?我认为将其分为多个测试是一个好主意。单独测试每种方法。你的意思是什么?我想在这里测试的唯一方法是
push\u action
。我的方法的“真实”行为是由
start\u线程处理的,但它不应该影响我的单元测试,对吗?