tutorial tests run rails matchers how factorybot ruby testing rspec scope default-scope

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