RSpec:使用线程进行测试

Nic*_*ker 9 ruby multithreading unit-testing rspec

在RSpec中,我有一个创建新线程的函数,并且在该线程内部执行一些操作 - 在我的情况下,调用TCPSocket#readline.这是现在的功能:

def read
  Thread.new do
    while line = @socket.readline
      #TODO: stuff
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

由于线程调度,如果这样写,我的测试将失败:

it "reads from socket" do
  subject.socket.should_receive(:readline)
  subject.read
end
Run Code Online (Sandbox Code Playgroud)

目前,我知道解决这个问题的唯一方法是使用sleep 0.1.有没有办法正确延迟测试,直到该线程运行?

Win*_*eld 9

如果你的目标是断言系统状态是由第二个线程的执行而改变的,那么你应该加入主测试线程中的第二个线程:

it "reads from socket" do
  subject.socket.should_receive(:readline)
  socket_thread = subject.read
  socket_thread.join
end
Run Code Online (Sandbox Code Playgroud)


Tre*_*urk 5

这是一个小技巧,但这里有一个before块,您可以使用它,以防您希望线程yield能够join在线程末尾调用。

before do
  allow(Thread).to receive(:new).and_yield.and_return(Class.new { def join; end }.new)
end
Run Code Online (Sandbox Code Playgroud)