我正在为DataMapper编写一个delayed_job
克隆。除了工作进程中的线程之外,我已经得到了我认为正在工作和测试的代码。我查看delayed_job
如何测试这个,但现在有对该部分代码的测试。下面是我需要测试的代码。想法? (我正在使用rspec BTW)
def start
say "*** Starting job worker #{@name}"
t = Thread.new do
loop do
delay = Update.work_off(self) #this method well tested
break if $exit
sleep delay
break if $exit
end
clear_locks
end
trap('TERM') { terminate_with t }
trap('INT') { terminate_with t }
trap('USR1') do
say "Wakeup Signal Caught"
t.run
end
答案 0 :(得分:9)
我认为,最好的方法是保留Thread.new
方法,并确保任何"复杂的"东西是它自己的方法,可以单独测试。因此你会有这样的事情:
class Foo
def start
Thread.new do
do_something
end
end
def do_something
loop do
foo.bar(bar.foo)
end
end
end
然后你会像这样测试:
describe Foo
it "starts thread running do_something" do
f = Foo.new
expect(Thread).to receive(:new).and_yield
expect(f).to receive(:do_something)
f.start
end
it "do_something loops with and calls foo.bar with bar.foo" do
f = Foo.new
expect(f).to receive(:loop).and_yield #for multiple yields: receive(:loop).and_yield.and_yield.and_yield...
expect(foo).to receive(:bar).with(bar.foo)
f.do_something
end
end
这样你就不必为了获得理想的结果而烦恼不已。
答案 1 :(得分:3)
您可以在测试时将工作程序作为子进程启动,等待它完全启动,然后检查输出/发送信号。
我怀疑你可以从Unicorn项目中找到这方面的一些具体测试想法。
答案 2 :(得分:0)
完全测试线程是不可能的。你能做的最好就是使用模拟器。
(类似的东西) object.should_recieve(:trap).with('TERM')。和yield object.start
答案 3 :(得分:0)
如何让测试中的线程正确。
Thread.stub(:new).and_yield
start
# assertions...