ruby-on-rails - run - rspec spectroscopy




Come posso eliminare find_each per rspec testing in rails 3 (3)

Mi stavo chiedendo come testare una chiamata find_each in rspec. Sono abituato a semplicemente ripetere ciò che voglio che i miei modelli restituiscano, quindi non mi affido ai dati di test nel db come questo:

MyClass.stub(:find).and_return(my_mock)

Tuttavia, in un'altra classe sto facendo questo:

MyClass.find_each do |instance_of_my_class|
  do_stuff_here_on(instance_of_my_class)
end

Trovo che se faccio questo:

MyClass.stub(:find_each).and_return([one_mock, two_mock])

nel test delle specifiche, la parte "fare cose qui" non viene eseguita. Qualcuno sa come fermare un find_each per il test di rspec?


L'intero punto di stub di un metodo è tale che il metodo restituisce un valore previsto e non esegue il suo contenuto. Se hai un po 'di logica nel metodo find_each, ti consiglio di spostarlo su un metodo separato e testare quella logica separatamente. È quindi possibile verificare che il metodo venga chiamato durante l'esecuzione.

Ecco un esempio di alto livello:

class Example1
  def my_method
    # some logic
  end
end

class Example2
  def my_other_method
    Example1.find_each(&:my_method)
  end
end

RSpec:

describe Example1 do
  it "should return something" do
    example = Example1.new
    example.my_method.should == something
  end
end

describe Example2 do
  it "should call my_method on Example1" do
    example1 = mock(:example1, :my_method => true)
    example2 = Example2.new

    example1.should_receive(:my_method)
    example2.my_other_method
  end
end

Puoi usare and_yield per fare in modo che rspec chiami il blocco passato alla simulazione:

MyClass.stub(:find_each).and_yield(one_mock).and_yield(two_mock)

Se hai bisogno di find_each su un doppio verificato e farlo scorrere attraverso una specifica matrice di valori, puoi farlo:

let(:my_relation_with_mocked_find_each) do
  relation = instance_double('YourModel::ActiveRecord_Relation')

  receive_yield = receive(:find_each)

  fake_objs.each do |obj|
    receive_yield = receive_yield.and_yield(obj)
  end

  allow(relation).to receive_yield
  relation
end






rspec2