test du code en Ruby
-
05-07-2019 - |
Question
J'écris un clone delay_job
pour DataMapper. J'ai ce que je pense fonctionne et code testé à l'exception du thread dans le processus de travail. J'ai regardé delay_job
pour savoir comment tester cela, mais il existe maintenant des tests pour cette partie du code. Vous trouverez ci-dessous le code que je dois tester. des idées? (J'utilise 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
voir aussi ce fil
La solution
Vous pouvez démarrer le poste de travail en tant que sous-processus lors du test, attendre qu'il démarre complètement, puis vérifier les signaux de sortie / envoi qui lui sont envoyés.
Je suppose que le projet Unicorn propose quelques idées de test concrètes dans ce domaine.
Autres conseils
Thread.new
et à vous assurer que toute méthode "compliquée" les choses sont dans sa propre méthode qui peut être testée 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 testez 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 à faire beaucoup de efforts pour obtenir le résultat souhaité.
Il est impossible de tester complètement les threads. Le mieux que vous puissiez faire est d’utiliser des simulacres.
(quelque chose comme) object.should_recieve (: trap) .with ('TERM'). et céder object.start
Que diriez-vous simplement que le fil cède sa place dans votre test?
Thread.stub(:new).and_yield
start
# assertions...