Domanda

Sto scrivendo un clone delayed_job per DataMapper. Ho quello che penso stia funzionando e testato il codice ad eccezione del thread nel processo di lavoro. Ho cercato delayed_job per sapere come testarlo, ma ora ci sono test per quella parte del codice. Di seguito è riportato il codice che devo testare. idee? (Sto usando 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

vedi anche questa discussione

È stato utile?

Soluzione

È possibile avviare il lavoratore come sottoprocesso durante il test, in attesa che si avvii completamente, quindi controllare i segnali di output / invio ad esso.

Sospetto che tu possa raccogliere alcune idee concrete per i test in quest'area dal progetto Unicorn .

Altri suggerimenti

L'approccio migliore, credo, è quello di stub il metodo Thread.new e assicurarsi che qualsiasi "complicato" roba è nel suo metodo che può essere testato individualmente. Quindi avresti qualcosa del genere:

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

Quindi proveresti in questo modo:

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

In questo modo non è necessario muoversi così tanto per ottenere il risultato desiderato.

È impossibile testare completamente i thread. Il meglio che puoi fare è usare le beffe.

(qualcosa del genere)     object.should_recieve (: trap) .with ('TERM'). e yield     object.start

Che ne dici di avere il giusto rendimento del thread nel tuo test.

Thread.stub(:new).and_yield
start
# assertions...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top