2009-10-22 3 views
4

J'écris un clone delayed_job pour DataMapper. J'ai ce que je pense fonctionne et a testé le code à l'exception du thread dans le processus de travail. J'ai regardé delayed_job pour savoir comment tester cela mais il y a maintenant des tests pour cette partie du code. Voici le code que j'ai besoin de tester. des idées? (J'utilise rspec BTW)tester le code fileté dans 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 

voir aussi this thread

+0

"voir aussi ce fil" - était-ce intentionnel? –

+0

Seulement si vous le vouliez –

Répondre

3

Vous pourriez commencer le travailleur comme un sous-processus lors de l'essai, en attendant qu'il pleinement démarrez, puis vérifiez les signaux de sortie/envoi.

Je suppose que vous pouvez trouver quelques idées de tests concrets dans ce domaine à partir du projet Unicorn.

0

Il est impossible de tester des fils complètement. Le mieux que vous pouvez faire est d'utiliser des simulacres.

(quelque chose comme) object.should_recieve (: piège). .avec (« TERME ») et le rendement object.start

0

Que diriez-vous d'avoir juste le rendement de fil dans votre test.

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

La meilleure approche, je crois, est de bouchonner la méthode Thread.new, et assurez-vous que toute substance « compliquée » est dans sa propre méthode qui peut être testé individuellement. Ainsi, vous auriez quelque chose comme ceci:

class Foo 
    def start 
     Thread.new do 
      do_something 
     end 
    end 
    def do_something 
     loop do 
      foo.bar(bar.foo) 
     end 
    end 
end 

Ensuite, vous tester comme ceci:

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 

De cette façon, vous n'avez pas Hax autour tant pour obtenir le résultat souhaité.

+1

C'est ainsi que j'ai résolu mon problème. Merci! – Arnlen

+0

@Arnlen Content de pouvoir aider :) – Automatico