ruby - tests - rspec tutorial
¿Cómo puedo tener la prueba rspec para mi alcance por defecto (3)
Secarlo, usar ejemplos compartidos
Lo más probable es que tengas más de un modelo con un alcance predeterminado similar (si no, en su mayoría, ignora este método), por lo que puedes poner este ejemplo de Rspec en un ejemplo compartido donde puedes llamarlo desde una variedad de especificaciones de modelo.
Mi método preferido para verificar un alcance predeterminado es asegurarme de que ActiveRecord::Relation
predeterminado tenga la cláusula esperada ( order
o where
o where
sea el caso), así:
spec / support / shared_examples / default_scope_examples.rb
shared_examples_for ''a default scope ordered by created_at'' do
it ''adds a clause to order by created_at'' do
described_class.scoped.order_clauses.should include("created_at")
end
end
Y luego en su especificación CatMembership
(y cualquier otra especificación que tenga el mismo alcance predeterminado), todo lo que necesita es:
spec / models / cat_membership_spec.rb
describe CatMembership
it_behaves_like ''a default scope ordered by created_at''
# other spec examples #
end
Finalmente, puede ver cómo este patrón se puede extender a todo tipo de ámbitos predeterminados y mantiene las cosas limpias, organizadas y, lo mejor de todo, SECAS.
mi modelo tiene default_scope (: order => ''created_at'') mis pruebas (rspec, factory girl, shoulda, etc.) son:
require ''spec/spec_helper.rb''
describe CatMembership do
context "is valid" do
subject { Factory.build(:cat_membership) }
it { should be_valid }
it { should belong_to :cat}
it { should belong_to :cat_group}
it { should have_db_column(:start_date)}
it { should have_db_column(:end_date)}
end
end
De acuerdo con las últimas convenciones de RSpec
se recomienda expect
, en lugar de should
, una mejor respuesta sería
expect(CatMembership.scoped.to_sql).to eq(CatMembership.order(:created_at).to_sql)
Sin embargo, últimamente Model.scoped
está en desuso, por lo que se recomienda usar Model.all
en Model.all
lugar.
expect(CatMembership.all.to_sql).to eq(CatMembership.order(:created_at).to_sql)
Preferiría que esto se probara mediante una consulta y verificando los resultados, pero si realmente debe hacerlo, una posible solución sería algo como esto para Rails 3:
CatMembership.scoped.to_sql.should == CatMembership.order(:created_at).to_sql
Y en Rails 2:
CatMembership.default_scoping.should == [{:create=>{}, :find=>{:order=>"created_at"}}]
Pero no diría que estas soluciones son ideales, ya que muestran un gran conocimiento de la implementación (y se puede ver que la implementación varía según las diferentes versiones de Rails).
La creación de datos de muestra, la ejecución de todas las consultas habituales y la verificación del resultado ordenado correctamente podrían haber sido más sencillas, estar más cerca de las pruebas de unidades reales y funcionar incluso cuando actualice la versión de los rieles.
En este caso posiblemente sería:
before do
@memberships = []
@memberships << CatMembership.create!
@memberships << CatMembership.create!
@memberships << CatMembership.create!
[ 1.hour.ago, 5.minutes.ago, 1.minute.ago ].each_with_index do |time, index|
membership = @memberships[index]
membership.created_at = time
membership.save
end
end
it ''should be correctly ordered'' do
@sorted_memberships = CatMembership.all
@memberships.first.should == @sorted_memberships.last
@memberships.second.should == @sorted_memberships.second
@memberships.third.should == @sorted_memberships.first
end
Es mucho más detallado, pero funcionará incluso a medida que avanzas en los rieles.
Y ahora me acabo de dar cuenta de quién hizo la pregunta: D