J'ai un modèle avec une méthode privée que je voudrais spécifier avec RSpec,
comment faites-vous habituellement? Testez-vous uniquement la méthode appelant la méthode privée?
ou spécifiez également le privé? si oui, comment faites-vous?
Je prends toujours cette approche: je veux tester l'API publique que ma classe expose.
Si vous avez des méthodes privées, vous ne les appelez qu'à partir des méthodes publiques que vous exposez à d'autres classes. Par conséquent, si vous testez que ces méthodes publiques fonctionnent comme prévu dans toutes les conditions, vous avez également prouvé que les méthodes privées qu'elles utilisent fonctionnent également.
J'avoue que j'ai rencontré des méthodes privées particulièrement complexes. Dans ce cas extrême où vous souhaitez les tester, vous pouvez le faire:
@obj.send(:private_method)
Pour les méthodes privées qui nécessitent une couverture de code (temporairement ou définitivement), utilisez la rspec-context-private gem pour rendre temporairement des méthodes privées publiques dans un contexte.
gem 'rspec-context-private'
Cela fonctionne en ajoutant un contexte partagé à votre projet.
RSpec.shared_context 'private', private: true do
before :all do
described_class.class_eval do
@original_private_instance_methods = private_instance_methods
public *@original_private_instance_methods
end
end
after :all do
described_class.class_eval do
private *@original_private_instance_methods
end
end
end
Ensuite, si vous passez :private
en tant que métadonnées d'un bloc describe
, les méthodes privées seront publiques dans ce contexte.
class Example
private def foo
'bar'
end
end
describe Example, :private do
it 'can test private methods' do
expect(subject.foo).not eq 'bar'
end
end
Si vous souhaitez tester une attente sur une méthode privée, la réponse acceptée ne fonctionnera pas vraiment (du moins pas à ma connaissance, je suis donc ouvert à la correction sur ce point). Ce que j'ai fait à la place est encore plus sale - dans le test lui-même, il suffit d'exposer la méthode en la redéfinissant:
def object_to_test.my_private_method
super
end
Fonctionne sur Ruby 1.8, ne peut commenter aucun des nouveaux runtimes.