2009-10-22 57 views
4

我正在为DataMapper编写一个delayed_job克隆。我已经得到了我认为正在工作和测试的代码,除了工作进程中的线程。我期待delayed_job如何测试,但现在有测试代码的那部分。以下是我需要测试的代码。想法? (我使用rspec的BTW)在ruby中测试线程代码

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 

this thread

+0

“又见这个线索” - 那双双有意? – 2011-07-01 10:41:13

+0

只有当你想要它时 – 2011-07-01 20:44:21

回答

3

你可以启动工作作为子测试时,等待它完全开始,然后检查输出/发送信号。

我怀疑你可以从Unicorn这个项目中找到这方面的一些具体测试思路。

0

看到它不可能测试线完全。最好你可以做的是使用嘲笑。

(像) object.should_recieve(:陷阱)。。随着( 'TERM')和屈服 object.start

0

如何让线程在测试中正确输出?

Thread.stub(:new).and_yield 
start 
# assertions... 
8

最好的方法,我相信,是存根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 

这样你就不必HAX各地这么多的得到期望的结果。

+1

这是解决我的问题的方式。谢谢! – Arnlen 2015-04-15 14:18:20

+0

@Arnlen很高兴我能帮忙:) – Automatico 2015-04-16 13:50:14