带螺纹的Rspec

时间:2018-02-02 15:11:43

标签: ruby multithreading rspec

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

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测试这个类来检查当我传递一些动作时会发生什么。但我不知道该怎么做。

提前致谢

1 个答案:

答案 0 :(得分:0)

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

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

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