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

Était-ce utile?

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

La meilleure approche, à mon avis, consiste à arrêter la méthode 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...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top