Pregunta ¿Cómo puedo encontrar find_each para la prueba de rspec en rieles 3?


Me preguntaba cómo probar una llamada find_each en rspec. Estoy acostumbrado a anotar lo que quiero que devuelvan mis modelos, así que no confío en los datos de prueba en el DB de esta manera:

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

Sin embargo, en otra clase estoy haciendo esto:

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

Me parece que si hago esto:

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

en la prueba de especificación, la parte "hacer cosas aquí" no se está ejecutando. ¿Alguien sabe cómo encontrar un find_each para la prueba de rspec?


32
2017-12-07 23:18


origen


Respuestas:


Puede usar and_yield para hacer que rspec invoque el bloque pasado al simulacro:

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

37
2017-12-08 07:15



El objetivo de anotar un método es que el método devuelva un valor esperado y no ejecute su contenido. Si tiene un montón de lógica dentro del método find_each, recomendaría moverlo a un método diferente y probar esa lógica por separado. Luego puede probar que se llama a su método durante la ejecución.

Aquí hay un ejemplo de alto nivel:

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

2
2017-12-08 02:15



Esto debería hacerlo:

MyClass.stub(:find_each) {|block|
  block.call
  [one_mock, two_mock]
}

Si do_stuff_here_on no es alcanzable globalmente, p. un método de instancia en some_object, necesitarás algunos instance_eval para obtener el alcance correcto para el bloque:

MyClass.stub(:find_each) {|block|
  some_object.instance_eval(&block)
  [one_mock, two_mock]
}

1
2017-11-21 08:47