ruby on rails - Rieles: ¿Cómo probar state_machine?
ruby-on-rails rspec (4)
Desafortunadamente, creo que es necesario realizar una prueba para cada estado -> transición de estado, que puede parecer una duplicación de código.
describe Ratification do
it "should initialize to :boss" do
r = Ratification.new
r.boss?.should == true
end
it "should move from :boss to :owner to :done as it''s approved" do
r = Ratification.new
r.boss?.should == true
r.approve
r.owner?.should == true
r.approve
r.done?.should == true
end
# ...
end
Afortunadamente, creo que esto generalmente encaja en las pruebas de integración. Por ejemplo, una máquina de estado extremadamente simple para un sistema de pagos sería:
class Bill < ActiveRecord::Base
belongs_to :account
attr_protected :status_events
state_machine :status, :initial => :unpaid do
state :unpaid
state :paid
event :mark_as_paid do
transition :unpaid => :paid
end
end
end
Es posible que aún tengas las pruebas unitarias como anteriormente, pero probablemente también tengas pruebas de integración, algo como:
describe Account do
it "should mark the most recent bill as paid" do
@account.recent_bill.unpaid?.should == true
@account.process_creditcard(@credit_card)
@account.recent_bill.paid?.should == true
end
end
Eso fue un montón de mano en espera, pero espero que tenga sentido. Tampoco estoy muy acostumbrado a RSpec, así que espero no haber cometido demasiados errores allí. Si hay una forma más elegante de probar esto, todavía no la he encontrado.
Por favor, ayúdame. Estoy confundido. Sé cómo escribir el comportamiento del modelo impulsado por el estado, pero no sé qué debo escribir en las especificaciones ...
Mi archivo model.rb mira
class Ratification < ActiveRecord::Base
belongs_to :user
attr_protected :status_events
state_machine :status, :initial => :boss do
state :boss
state :owner
state :declarant
state :done
event :approve do
transition :boss => :owner, :owner => :done
end
event :divert do
transition [:boss, :owner] => :declarant
end
event :repeat do
transition :declarant => :boss
end
end
end
Yo uso la gema state_machine .
Por favor, muéstrame el curso.
He escrito un emparejador personalizado RSpec. Permite probar el flujo de estado de manera elegante y simple: échale un vistazo
La gema state_machine_rspec incluye muchos métodos de ayuda para escribir especificaciones concisas.
describe Ratification do
it { should have_states :boss, :declarant, :done, :owner }
it { should handle_events :approve, when: :boss }
it { should handle_events :approve, when: :owner }
it { should handle_events :divert, when: :boss }
it { should handle_events :divert, when: :owner }
it { should handle_events :repeat, when: :declarant }
it { should reject_events :approve, :divert, :repeat, when: :done }
it { should reject_events :approve, :divert, :repeat, when: :done }
end
Estos emparejadores RSpec ayudarán con las especificaciones de state_machine
desde un alto nivel. A partir de aquí, ¿hay que escribir las especificaciones para los casos de negocio para can_approve?
, can_divert?
y can_repeat?
.
La pregunta es vieja, pero yo tenía la misma. Tomando el ejemplo de la gema state_machine :
class Vehicle
state_machine :state, :initial => :parked do
event :park do
transition [:idling, :first_gear] => :parked
end
event :ignite do
transition :stalled => same, :parked => :idling
end
event :idle do
transition :first_gear => :idling
end
event :shift_up do
transition :idling => :first_gear, :first_gear => :second_gear, :second_gear => :third_gear
end
event :shift_down do
transition :third_gear => :second_gear, :second_gear => :first_gear
end
end
end
Mi solución fue:
describe Vehicle do
before :each do
@vehicle = Factory(:vehicle)
end
describe ''states'' do
describe '':parked'' do
it ''should be an initial state'' do
# Check for @vehicle.parked? to be true
@vehicle.should be_parked
end
it ''should change to :idling on :ignite'' do
@vehicle.ignite!
@vehicle.should be_idling
end
[''shift_up!'', ''shift_down!''].each do |action|
it "should raise an error for #{action}" do
lambda {@job_offer.send(action)}.should raise_error
end
end
end
end
end
Estaba usando
- rubí (1.9.3)
- rieles (3.1.3)
- rspec (2.8.0.rc1)
- factory_girl (2.3.2)
- state_machine (1.1.0)