Étant donné que j'ai un problème Personable
dans mon application Rails 4 qui a un full_name
méthode, comment pourrais-je tester cela avec RSpec?
soucis/personable.rb
module Personable
extend ActiveSupport::Concern
def full_name
"#{first_name} #{last_name}"
end
end
La méthode que vous avez trouvée fonctionnera certainement pour tester un peu de fonctionnalité mais semble assez fragile - votre classe fictive (en réalité juste un Struct
dans votre solution) peut ou non se comporter comme une vraie classe qui include
s votre préoccupation. De plus, si vous essayez de tester les problèmes de modèle, vous ne pourrez pas effectuer de tâches telles que tester la validité des objets ou appeler des rappels ActiveRecord, sauf si vous configurez la base de données en conséquence (car votre classe factice n'aura pas de sauvegarde de table de base de données). il). En outre, vous souhaiterez non seulement tester le problème, mais également son comportement dans les spécifications de votre modèle.
Alors, pourquoi ne pas faire d'une pierre deux coups? En utilisant les exemples de groupes partagés de RSpec, vous pouvez tester vos préoccupations par rapport aux classes qui les utilisent (par exemple, les modèles) et vous pourrez les tester partout où ils sont utilisés. Et il vous suffit d'écrire les tests une fois, puis de les inclure dans toute spécification de modèle qui utilise votre préoccupation. Dans votre cas, cela pourrait ressembler à ceci:
# app/models/concerns/personable.rb
module Personable
extend ActiveSupport::Concern
def full_name
"#{first_name} #{last_name}"
end
end
# spec/concerns/personable_spec.rb
require 'spec_helper'
shared_examples_for "personable" do
let(:model) { described_class } # the class that includes the concern
it "has a full name" do
person = FactoryBot.build(model.to_s.underscore.to_sym, first_name: "Stewart", last_name: "Home")
expect(person.full_name).to eq("Stewart Home")
end
end
# spec/models/master_spec.rb
require 'spec_helper'
require Rails.root.join "spec/concerns/personable_spec.rb"
describe Master do
it_behaves_like "personable"
end
# spec/models/apprentice_spec.rb
require 'spec_helper'
describe Apprentice do
it_behaves_like "personable"
end
Les avantages de cette approche deviennent encore plus évidents lorsque vous commencez à faire des choses dans votre préoccupation, comme invoquer des rappels AR, où rien de moins qu'un objet AR ne suffira.
En réponse aux commentaires que j'ai reçus, voici ce que j'ai fini par faire (si quelqu'un a des améliorations, n'hésitez pas à les poster) :
spec/concerne/personable_spec.rb
require 'spec_helper'
describe Personable do
let(:test_class) { Struct.new(:first_name, :last_name) { include Personable } }
let(:personable) { test_class.new("Stewart", "Home") }
it "has a full_name" do
expect(personable.full_name).to eq("#{personable.first_name} #{personable.last_name}")
end
end
Une autre pensée consiste à utiliser le with_model gem pour tester de telles choses. Je cherchais à tester moi-même un problème et j'avais vu le pg_search gem le faisant . Cela semble beaucoup mieux que de tester sur des modèles individuels, car ceux-ci pourraient changer, et il est agréable de définir les éléments dont vous aurez besoin dans vos spécifications.