class RuboCop::Cop::RSpec::SubjectStub
Checks for stubbed test subjects.
Checks nested subject stubs for innermost subject definition when subject is also defined in parent example groups.
@see robots.thoughtbot.com/don-t-stub-the-system-under-test @see penelope.zone/2015/12/27/introducing-rspec-smells-and-where-to-find-them.html#smell-1-stubjec
@example
# bad describe Article do subject(:article) { Article.new } it 'indicates that the author is unknown' do allow(article).to receive(:author).and_return(nil) expect(article.description).to include('by an unknown author') end end # bad describe Article do subject(:foo) { Article.new } context 'nested subject' do subject(:article) { Article.new } it 'indicates that the author is unknown' do allow(article).to receive(:author).and_return(nil) expect(article.description).to include('by an unknown author') end end end # good describe Article do subject(:article) { Article.new(author: nil) } it 'indicates that the author is unknown' do expect(article.description).to include('by an unknown author') end end
Constants
- MSG
Public Instance Methods
on_top_level_group(node)
click to toggle source
# File lib/rubocop/cop/rspec/subject_stub.rb, line 115 def on_top_level_group(node) @explicit_subjects = find_all_explicit(node) { |n| subject?(n) } @subject_overrides = find_all_explicit(node) { |n| let?(n) } find_subject_expectations(node) do |stub| add_offense(stub) end end
Private Instance Methods
find_all_explicit(node) { |child| ... }
click to toggle source
# File lib/rubocop/cop/rspec/subject_stub.rb, line 126 def find_all_explicit(node) node.each_descendant(:block).with_object({}) do |child, h| name = yield(child) next unless name outer_example_group = child.each_ancestor(:block).find do |a| example_group?(a) end h[outer_example_group] ||= [] h[outer_example_group] << name end end
find_subject_expectations(node, subject_names = []) { |node| ... }
click to toggle source
# File lib/rubocop/cop/rspec/subject_stub.rb, line 140 def find_subject_expectations(node, subject_names = [], &block) subject_names = [*subject_names, *@explicit_subjects[node]] subject_names -= @subject_overrides[node] if @subject_overrides[node] names = Set[*subject_names, :subject] expectation_detected = message_expectation?(node, names) return yield(node) if expectation_detected node.each_child_node(:send, :def, :block, :begin) do |child| find_subject_expectations(child, subject_names, &block) end end