gpt4 book ai didi

ruby - 如何rspec线程代码?

转载 作者:数据小太阳 更新时间:2023-10-29 08:47:51 24 4
gpt4 key购买 nike



开始使用 rspec 我在尝试测试线程代码时遇到了困难。这是创建的代码的简化,我之所以这样做是因为我需要一个具有超时功能的队列

require "thread"

class TimeoutQueue
def initialize
@lock = Mutex.new
@items = []
@new_item = ConditionVariable.new
end

def push(obj)
@lock.synchronize do
@items.push(obj)
@new_item.signal
end
end

def pop(timeout = :never)
timeout += Time.now unless timeout == :never
@lock.synchronize do
loop do
time_left = timeout == :never ? nil : timeout - Time.now
if @items.empty? and time_left.to_f >= 0
@new_item.wait(@lock, time_left)
end
return @items.shift unless @items.empty?
next if timeout == :never or timeout > Time.now
return nil
end
end
end

alias_method :<<, :push
end

但我找不到使用 rspec 对其进行测试的方法。是否有任何关于测试线程代码的有效文档?任何可以帮助我的 gem ?我有点受阻,提前致谢

最佳答案

在进行单元测试时,我们不希望任何不确定的行为影响我们的测试,因此在测试线程时,我们不应并行运行任何东西。

相反,我们应该隔离我们的代码,并模拟我们想要测试的情况,方法是插入 @lock@new_item 和甚至 Time.now(为了更具可读性,我冒昧地假设您也有 attr_reader :lock, :new_item):

it 'should signal after push' do
allow(subject.lock).to receive(:synchronize).and_yield

expect(subject.new_item).to receive(:signal)

subject.push('object')

expect(subject.items).to include('object')
end

it 'should time out if taken to long to enter synchronize loop' do
@now = Time.now
allow(Time).to receive(:now).and_return(@now, @now + 10.seconds)
allow(subject.items).to receive(:empty?).and_return true
allow(subject.lock).to receive(:synchronize).and_yield

expect(subject.new_item).to_not receive(:wait)

expect(subject.pop(5.seconds)).to be_nil
end

等...

关于ruby - 如何rspec线程代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22112202/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com