RSpecでスペックしたいプライベートメソッドのモデルを取得しました。
通常はどのようにしていますか?プライベートメソッドを呼び出すメソッドのみをテストしますか?
またはプライベートのものも指定しますか?もしそうなら、あなたはどうしますか?
私は常にこのアプローチをとります:私のクラスが公開しているパブリックAPIをテストしたいと思います。
プライベートメソッドがある場合、他のクラスに公開するパブリックメソッドからのみそれらを呼び出します。したがって、これらのパブリックメソッドがすべての条件下で期待どおりに機能することをテストすると、それらが使用するプライベートメソッドも機能することが証明されます。
特に複雑なプライベートメソッドに遭遇したことを認めます。それらをテストしたい極端なケースでは、これを行うことができます:
@obj.send(:private_method)
(一時的または永続的に)コードカバレッジを必要とするプライベートメソッドの場合、 rspec-context-private gem を使用して、プライベートメソッドをコンテキスト内で一時的にパブリックにします。
gem 'rspec-context-private'
プロジェクトに共有コンテキストを追加することで機能します。
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
次に、:private
describe
ブロックへのメタデータとして、プライベートメソッドはそのコンテキスト内でパブリックになります。
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
プライベートメソッドで期待値をテストしたい場合、受け入れられた答えは実際には機能しません(少なくとも、私が知っていることではないので、その点については修正の余地があります)。代わりに私がやったことはさらに不潔です-テスト自体では、メソッドを再定義してメソッドを公開するだけです:
def object_to_test.my_private_method
super
end
Ruby 1.8で動作します。新しいランタイムにはコメントできません。