RSpec

RSpec/AlignLeftLetBrace

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

Yes

1.16

-

Checks that left braces for adjacent single line lets are aligned.

Examples

# bad
let(:foobar) { blahblah }
let(:baz) { bar }
let(:a) { b }

# good
let(:foobar) { blahblah }
let(:baz)    { bar }
let(:a)      { b }

RSpec/AlignRightLetBrace

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

Yes

1.16

-

Checks that right braces for adjacent single line lets are aligned.

Examples

# bad
let(:foobar) { blahblah }
let(:baz)    { bar }
let(:a)      { b }

# good
let(:foobar) { blahblah }
let(:baz)    { bar      }
let(:a)      { b        }

RSpec/AnyInstance

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.4

-

Check that instances are not being stubbed globally.

Prefer instance doubles over stubbing any instance of a class

Examples

# bad
describe MyClass do
  before { allow_any_instance_of(MyClass).to receive(:foo) }
end

# good
describe MyClass do
  let(:my_instance) { instance_double(MyClass) }

  before do
    allow(MyClass).to receive(:new).and_return(my_instance)
    allow(my_instance).to receive(:foo)
  end
end

RSpec/AroundBlock

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.11

-

Checks that around blocks actually run the test.

Examples

# bad
around do
  some_method
end

around do |test|
  some_method
end

# good
around do |test|
  some_method
  test.call
end

around do |test|
  some_method
  test.run
end

RSpec/Be

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.25

-

Check for expectations where be is used without argument.

The be matcher is too generic, as it pass on everything that is not nil or false. If that is the exact intend, use be_truthy. In all other cases it’s better to specify what exactly is the expected value.

Examples

# bad
expect(foo).to be

# good
expect(foo).to be_truthy
expect(foo).to be 1.0
expect(foo).to be(true)

RSpec/BeEql

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.7

-

Check for expectations where be(…​) can replace eql(…​).

The be matcher compares by identity while the eql matcher compares using eql?. Integers, floats, booleans, symbols, and nil can be compared by identity and therefore the be matcher is preferable as it is a more strict test.

This cop only looks for instances of expect(…​).to eql(…​). We do not check to_not or not_to since !eql? is more strict than !equal?. We also do not try to flag eq because if a == b, and b is comparable by identity, a is still not necessarily the same type as b since the #== operator can coerce objects for comparison.

Examples

# bad
expect(foo).to eql(1)
expect(foo).to eql(1.0)
expect(foo).to eql(true)
expect(foo).to eql(false)
expect(foo).to eql(:bar)
expect(foo).to eql(nil)

# good
expect(foo).to be(1)
expect(foo).to be(1.0)
expect(foo).to be(true)
expect(foo).to be(false)
expect(foo).to be(:bar)
expect(foo).to be(nil)

RSpec/BeforeAfterAll

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.12

-

Check that before/after(:all) isn’t being used.

Examples

# bad
#
# Faster but risk of state leaking between examples
#
describe MyClass do
  before(:all) { Widget.create }
  after(:all) { Widget.delete_all }
end

# good
#
# Slower but examples are properly isolated
#
describe MyClass do
  before(:each) { Widget.create }
  after(:each) { Widget.delete_all }
end

Configurable attributes

Name Default value Configurable values

Exclude

spec/spec_helper.rb, spec/rails_helper.rb, spec/support/*/.rb

Array

RSpec/ContextMethod

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.36

-

context should not be used for specifying methods.

Examples

# bad
context '#foo_bar' do
  # ...
end

context '.foo_bar' do
  # ...
end

# good
describe '#foo_bar' do
  # ...
end

describe '.foo_bar' do
  # ...
end

RSpec/ContextWording

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.20

1.20.1

Checks that context docstring starts with an allowed prefix.

The default list of prefixes is minimal. Users are encouraged to tailor the configuration to meet project needs. Other acceptable prefixes may include if, unless, for, before, after, or during.

Examples

Prefixes configuration

# .rubocop.yml
# RSpec/ContextWording:
#   Prefixes:
#     - when
#     - with
#     - without
#     - if
#     - unless
#     - for
# bad
context 'the display name not present' do
  # ...
end

# good
context 'when the display name is not present' do
  # ...
end

Configurable attributes

Name Default value Configurable values

Prefixes

when, with, without

Array

RSpec/DescribeClass

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.0

1.44

Check that the first argument to the top-level describe is a constant.

It can be configured to ignore strings when certain metadata is passed.

Ignores Rails and Aruba type metadata by default.

Examples

IgnoredMetadata configuration

# .rubocop.yml
# RSpec/DescribeClass:
#   IgnoredMetadata:
#     type:
#       - request
#       - controller
# bad
describe 'Do something' do
end

# good
describe TestedClass do
  subject { described_class }
end

describe 'TestedClass::VERSION' do
  subject { Object.const_get(self.class.description) }
end

describe "A feature example", type: :feature do
end

Configurable attributes

Name Default value Configurable values

IgnoredMetadata

{"type"⇒["channel", "controller", "helper", "job", "mailer", "model", "request", "routing", "view", "feature", "system", "mailbox", "aruba"]}

RSpec/DescribeMethod

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.0

-

Checks that the second argument to describe specifies a method.

Examples

# bad
describe MyClass, 'do something' do
end

# good
describe MyClass, '#my_instance_method' do
end

describe MyClass, '.my_class_method' do
end

RSpec/DescribeSymbol

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.15

-

Avoid describing symbols.

Examples

# bad
describe :my_method do
  # ...
end

# good
describe '#my_method' do
  # ...
end

RSpec/DescribedClass

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes (Unsafe)

1.0

1.11

Checks that tests use described_class.

If the first argument of describe is a class, the class is exposed to each example via described_class.

This cop can be configured using the EnforcedStyle and SkipBlocks options.

There’s a known caveat with rspec-rails’s controller helper that runs its block in a different context, and described_class is not available to it. SkipBlocks option excludes detection in all non-RSpec related blocks.

To narrow down this setting to only a specific directory, it is possible to use an overriding configuration file local to that directory.

Examples

EnforcedStyle: described_class

# bad
describe MyClass do
  subject { MyClass.do_something }
end

# good
describe MyClass do
  subject { described_class.do_something }
end

EnforcedStyle: explicit

# bad
describe MyClass do
  subject { described_class.do_something }
end

# good
describe MyClass do
  subject { MyClass.do_something }
end

SkipBlocks: true

# spec/controllers/.rubocop.yml
# RSpec/DescribedClass:
#   SkipBlocks: true

# acceptable
describe MyConcern do
  controller(ApplicationController) do
    include MyConcern
  end
end

Configurable attributes

Name Default value Configurable values

SkipBlocks

false

Boolean

EnforcedStyle

described_class

described_class, explicit

RSpec/DescribedClassModuleWrapping

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

No

1.37

-

Avoid opening modules and defining specs within them.

Examples

# bad
module MyModule
  RSpec.describe MyClass do
    # ...
  end
end

# good
RSpec.describe MyModule::MyClass do
  # ...
end

RSpec/Dialect

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

Yes

1.33

-

This cop enforces custom RSpec dialects.

A dialect can be based on the following RSpec methods:

  • describe, context, feature, example_group

  • xdescribe, xcontext, xfeature

  • fdescribe, fcontext, ffeature

  • shared_examples, shared_examples_for, shared_context

  • it, specify, example, scenario, its

  • fit, fspecify, fexample, fscenario, focus

  • xit, xspecify, xexample, xscenario, skip

  • pending

  • prepend_before, before, append_before,

  • around

  • prepend_after, after, append_after

  • let, let!

  • subject, subject!

  • expect, is_expected, expect_any_instance_of

By default all of the RSpec methods and aliases are allowed. By setting a config like:

RSpec/Dialect:
  PreferredMethods:
    context: describe

You can expect the following behavior:

Examples

# bad
context 'display name presence' do
  # ...
end

# good
describe 'display name presence' do
  # ...
end

Configurable attributes

Name Default value Configurable values

PreferredMethods

{}

RSpec/EmptyExampleGroup

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

-

Checks if an example group does not include any tests.

This cop is configurable using the CustomIncludeMethods option

Examples

usage

# bad
describe Bacon do
  let(:bacon)      { Bacon.new(chunkiness) }
  let(:chunkiness) { false                 }

  context 'extra chunky' do   # flagged by rubocop
    let(:chunkiness) { true }
  end

  it 'is chunky' do
    expect(bacon.chunky?).to be_truthy
  end
end

# good
describe Bacon do
  let(:bacon)      { Bacon.new(chunkiness) }
  let(:chunkiness) { false                 }

  it 'is chunky' do
    expect(bacon.chunky?).to be_truthy
  end
end

# good
describe Bacon do
  pending 'will add tests later'
end

configuration

# .rubocop.yml
# RSpec/EmptyExampleGroup:
#   CustomIncludeMethods:
#   - include_tests

# spec_helper.rb
RSpec.configure do |config|
  config.alias_it_behaves_like_to(:include_tests)
end

# bacon_spec.rb
describe Bacon do
  let(:bacon)      { Bacon.new(chunkiness) }
  let(:chunkiness) { false                 }

  context 'extra chunky' do   # not flagged by rubocop
    let(:chunkiness) { true }

    include_tests 'shared tests'
  end
end

Configurable attributes

Name Default value Configurable values

CustomIncludeMethods

[]

Array

RSpec/EmptyHook

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.39

-

Checks for empty before and after hooks.

Examples

# bad
before {}
after do; end
before(:all) do
end
after(:all) { }

# good
before { create_users }
after do
  cleanup_users
end
before(:all) do
  create_feed
end
after(:all) { cleanup_feed }

RSpec/EmptyLineAfterExample

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.36

-

Checks if there is an empty line after example blocks.

Examples

# bad
RSpec.describe Foo do
  it 'does this' do
  end
  it 'does that' do
  end
end

# good
RSpec.describe Foo do
  it 'does this' do
  end

  it 'does that' do
  end
end

# fair - it's ok to have non-separated one-liners
RSpec.describe Foo do
  it { one }
  it { two }
end

with AllowConsecutiveOneLiners configuration

# rubocop.yml
# RSpec/EmptyLineAfterExample:
#   AllowConsecutiveOneLiners: false

# bad
RSpec.describe Foo do
  it { one }
  it { two }
end

Configurable attributes

Name Default value Configurable values

AllowConsecutiveOneLiners

true

Boolean

RSpec/EmptyLineAfterExampleGroup

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.27

-

Checks if there is an empty line after example group blocks.

Examples

# bad
RSpec.describe Foo do
  describe '#bar' do
  end
  describe '#baz' do
  end
end

# good
RSpec.describe Foo do
  describe '#bar' do
  end

  describe '#baz' do
  end
end

RSpec/EmptyLineAfterFinalLet

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.14

-

Checks if there is an empty line after the last let block.

Examples

# bad
let(:foo) { bar }
let(:something) { other }
it { does_something }

# good
let(:foo) { bar }
let(:something) { other }

it { does_something }

RSpec/EmptyLineAfterHook

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.27

-

Checks if there is an empty line after hook blocks.

Examples

# bad
before { do_something }
it { does_something }

# bad
after { do_something }
it { does_something }

# bad
around { |test| test.run }
it { does_something }

# good
before { do_something }

it { does_something }

# good
after { do_something }

it { does_something }

# good
around { |test| test.run }

it { does_something }

RSpec/EmptyLineAfterSubject

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.14

-

Checks if there is an empty line after subject block.

Examples

# bad
subject(:obj) { described_class }
let(:foo) { bar }

# good
subject(:obj) { described_class }

let(:foo) { bar }

RSpec/ExampleLength

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.5

-

Checks for long examples.

A long example is usually more difficult to understand. Consider extracting out some behaviour, e.g. with a let block, or a helper method.

Examples

# bad
it do
  service = described_class.new
  more_setup
  more_setup
  result = service.call
  expect(result).to be(true)
end

# good
it do
  service = described_class.new
  result = service.call
  expect(result).to be(true)
end

Configurable attributes

Name Default value Configurable values

Max

5

Integer

RSpec/ExampleWithoutDescription

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.22

-

Checks for examples without a description.

RSpec allows for auto-generated example descriptions when there is no description provided or the description is an empty one.

This cop removes empty descriptions. It also defines whether auto-generated description is allowed, based on the configured style.

This cop can be configured using the EnforcedStyle option

Examples

EnforcedStyle: always_allow

# bad
it('') { is_expected.to be_good }
it '' do
  result = service.call
  expect(result).to be(true)
end

# good
it { is_expected.to be_good }
it do
  result = service.call
  expect(result).to be(true)
end

EnforcedStyle: single_line_only

# bad
it('') { is_expected.to be_good }
it do
  result = service.call
  expect(result).to be(true)
end

# good
it { is_expected.to be_good }

EnforcedStyle: disallow

# bad
it { is_expected.to be_good }
it do
  result = service.call
  expect(result).to be(true)
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

always_allow

always_allow, single_line_only, disallow

RSpec/ExampleWording

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.0

1.2

Checks for common mistakes in example descriptions.

This cop will correct docstrings that begin with 'should' and 'it'.

The autocorrect is experimental - use with care! It can be configured with CustomTransform (e.g. have ⇒ has) and IgnoredWords (e.g. only).

Examples

# bad
it 'should find nothing' do
end

# good
it 'finds nothing' do
end
# bad
it 'it does things' do
end

# good
it 'does things' do
end

Configurable attributes

Name Default value Configurable values

CustomTransform

{"be"⇒"is", "BE"⇒"IS", "have"⇒"has", "HAVE"⇒"HAS"}

IgnoredWords

[]

Array

RSpec/ExpectActual

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.7

-

Checks for expect(…​) calls containing literal values.

Examples

# bad
expect(5).to eq(price)
expect(/foo/).to eq(pattern)
expect("John").to eq(name)

# good
expect(price).to eq(5)
expect(pattern).to eq(/foo/)
expect(name).to eq("John")

Configurable attributes

Name Default value Configurable values

Exclude

spec/routing/*/

Array

RSpec/ExpectChange

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.22

-

Checks for consistent style of change matcher.

Enforces either passing object and attribute as arguments to the matcher or passing a block that reads the attribute value.

This cop can be configured using the EnforcedStyle option.

Examples

EnforcedStyle: block

# bad
expect { run }.to change(Foo, :bar)

# good
expect { run }.to change { Foo.bar }

EnforcedStyle: method_call

# bad
expect { run }.to change { Foo.bar }
expect { run }.to change { foo.baz }

# good
expect { run }.to change(Foo, :bar)
expect { run }.to change(foo, :baz)
# also good when there are arguments or chained method calls
expect { run }.to change { Foo.bar(:count) }
expect { run }.to change { user.reload.name }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

method_call

method_call, block

RSpec/ExpectInHook

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.16

-

Do not use expect in hooks such as before.

Examples

# bad
before do
  expect(something).to eq 'foo'
end

# bad
after do
  expect_any_instance_of(Something).to receive(:foo)
end

# good
it do
  expect(something).to eq 'foo'
end

RSpec/ExpectOutput

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.10

-

Checks for opportunities to use expect { …​ }.to output.

Examples

# bad
$stdout = StringIO.new
my_app.print_report
$stdout = STDOUT
expect($stdout.string).to eq('Hello World')

# good
expect { my_app.print_report }.to output('Hello World').to_stdout

RSpec/FilePath

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.2

1.40

Checks that spec file paths are consistent and well-formed.

By default, this checks that spec file paths are consistent with the test subject and and enforces that it reflects the described class/module and its optionally called out method.

With the configuration option IgnoreMethods the called out method will be ignored when determining the enforced path.

With the configuration option CustomTransform modules or classes can be specified that should not as usual be transformed from CamelCase to snake_case (e.g. 'RuboCop' ⇒ 'rubocop' ).

With the configuration option SpecSuffixOnly test files will only be checked to ensure they end in '_spec.rb'. This option disables checking for consistency in the test subject or test methods.

Examples

# bad
whatever_spec.rb         # describe MyClass

# bad
my_class_spec.rb         # describe MyClass, '#method'

# good
my_class_spec.rb         # describe MyClass

# good
my_class_method_spec.rb  # describe MyClass, '#method'

# good
my_class/method_spec.rb  # describe MyClass, '#method'

when configuration is IgnoreMethods: true

# bad
whatever_spec.rb         # describe MyClass

# good
my_class_spec.rb         # describe MyClass

# good
my_class_spec.rb         # describe MyClass, '#method'

when configuration is SpecSuffixOnly: true

# good
whatever_spec.rb         # describe MyClass

# good
my_class_spec.rb         # describe MyClass

# good
my_class_spec.rb         # describe MyClass, '#method'

Configurable attributes

Name Default value Configurable values

CustomTransform

{"RuboCop"⇒"rubocop", "RSpec"⇒"rspec"}

IgnoreMethods

false

Boolean

SpecSuffixOnly

false

Boolean

RSpec/Focus

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.5

-

Checks if examples are focused.

Examples

# bad
describe MyClass, focus: true do
end

describe MyClass, :focus do
end

fdescribe MyClass do
end

# good
describe MyClass do
end

RSpec/HookArgument

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.7

-

Checks the arguments passed to before, around, and after.

This cop checks for consistent style when specifying RSpec hooks which run for each example. There are three supported styles: "implicit", "each", and "example." All styles have the same behavior.

Examples

when configuration is EnforcedStyle: implicit

# bad
before(:each) do
  # ...
end

# bad
before(:example) do
  # ...
end

# good
before do
  # ...
end

when configuration is EnforcedStyle: each

# bad
before(:example) do
  # ...
end

# good
before do
  # ...
end

# good
before(:each) do
  # ...
end

when configuration is EnforcedStyle: example

# bad
before(:each) do
  # ...
end

# bad
before do
  # ...
end

# good
before(:example) do
  # ...
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

implicit

implicit, each, example

RSpec/HooksBeforeExamples

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.29

-

Checks for before/around/after hooks that come after an example.

Examples

# Bad

it 'checks what foo does' do
  expect(foo).to be
end

before { prepare }
after { clean_up }

# Good
before { prepare }
after { clean_up }

it 'checks what foo does' do
  expect(foo).to be
end

RSpec/ImplicitBlockExpectation

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.35

-

Check that implicit block expectation syntax is not used.

Prefer using explicit block expectations.

Examples

# bad
subject { -> { do_something } }
it { is_expected.to change(something).to(new_value) }

# good
it 'changes something to a new value' do
  expect { do_something }.to change(something).to(new_value)
end

RSpec/ImplicitExpect

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.8

-

Check that a consistent implicit expectation style is used.

This cop can be configured using the EnforcedStyle option and supports the --auto-gen-config flag.

Examples

EnforcedStyle: is_expected

# bad
it { should be_truthy }

# good
it { is_expected.to be_truthy }

EnforcedStyle: should

# bad
it { is_expected.to be_truthy }

# good
it { should be_truthy }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

is_expected

is_expected, should

RSpec/ImplicitSubject

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.29

1.30

Checks for usage of implicit subject (is_expected / should).

This cop can be configured using the EnforcedStyle option

Examples

EnforcedStyle: single_line_only

# bad
it do
  is_expected.to be_truthy
end

# good
it { is_expected.to be_truthy }
it do
  expect(subject).to be_truthy
end

EnforcedStyle: disallow

# bad
it { is_expected.to be_truthy }

# good
it { expect(subject).to be_truthy }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

single_line_only

single_line_only, single_statement_only, disallow

RSpec/InstanceSpy

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.12

-

Checks for instance_double used with have_received.

Examples

# bad
it do
  foo = instance_double(Foo).as_null_object
  expect(foo).to have_received(:bar)
end

# good
it do
  foo = instance_spy(Foo)
  expect(foo).to have_received(:bar)
end

RSpec/InstanceVariable

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.0

1.7

Checks for instance variable usage in specs.

This cop can be configured with the option AssignmentOnly which will configure the cop to only register offenses on instance variable usage if the instance variable is also assigned within the spec

Examples

# bad
describe MyClass do
  before { @foo = [] }
  it { expect(@foo).to be_empty }
end

# good
describe MyClass do
  let(:foo) { [] }
  it { expect(foo).to be_empty }
end

with AssignmentOnly configuration

# rubocop.yml
# RSpec/InstanceVariable:
#   AssignmentOnly: false

# bad
describe MyClass do
  before { @foo = [] }
  it { expect(@foo).to be_empty }
end

# allowed
describe MyClass do
  it { expect(@foo).to be_empty }
end

# good
describe MyClass do
  let(:foo) { [] }
  it { expect(foo).to be_empty }
end

Configurable attributes

Name Default value Configurable values

AssignmentOnly

false

Boolean

RSpec/InvalidPredicateMatcher

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.16

-

Checks invalid usage for predicate matcher.

Predicate matcher does not need a question. This cop checks an unnecessary question in predicate matcher.

Examples

# bad
expect(foo).to be_something?

# good
expect(foo).to be_something

RSpec/ItBehavesLike

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.13

-

Checks that only one it_behaves_like style is used.

Examples

when configuration is EnforcedStyle: it_behaves_like

# bad
it_should_behave_like 'a foo'

# good
it_behaves_like 'a foo'

when configuration is EnforcedStyle: it_should_behave_like

# bad
it_behaves_like 'a foo'

# good
it_should_behave_like 'a foo'

Configurable attributes

Name Default value Configurable values

EnforcedStyle

it_behaves_like

it_behaves_like, it_should_behave_like

RSpec/IteratedExpectation

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.14

-

Check that all matcher is used instead of iterating over an array.

Examples

# bad
it 'validates users' do
  [user1, user2, user3].each { |user| expect(user).to be_valid }
end

# good
it 'validates users' do
  expect([user1, user2, user3]).to all(be_valid)
end

RSpec/LeadingSubject

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.7

1.14

Enforce that subject is the first definition in the test.

Examples

# bad
  let(:params) { blah }
  subject { described_class.new(params) }

  before { do_something }
  subject { described_class.new(params) }

  it { expect_something }
  subject { described_class.new(params) }
  it { expect_something_else }

# good
  subject { described_class.new(params) }
  let(:params) { blah }

# good
  subject { described_class.new(params) }
  before { do_something }

# good
  subject { described_class.new(params) }
  it { expect_something }
  it { expect_something_else }

RSpec/LeakyConstantDeclaration

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.35

-

Checks that no class, module, or constant is declared.

Constants, including classes and modules, when declared in a block scope, are defined in global namespace, and leak between examples.

If several examples may define a DummyClass, instead of being a blank slate class as it will be in the first example, subsequent examples will be reopening it and modifying its behaviour in unpredictable ways. Even worse when a class that exists in the codebase is reopened.

Anonymous classes are fine, since they don’t result in global namespace name clashes.

Examples

Constants leak between examples

# bad
describe SomeClass do
  OtherClass = Struct.new
  CONSTANT_HERE = 'I leak into global namespace'
end

# good
describe SomeClass do
  before do
    stub_const('OtherClass', Struct.new)
    stub_const('CONSTANT_HERE', 'I only exist during this example')
  end
end
# bad
describe SomeClass do
  class FooClass < described_class
    def double_that
      some_base_method * 2
    end
  end

  it { expect(FooClass.new.double_that).to eq(4) }
end

# good - anonymous class, no constant needs to be defined
describe SomeClass do
  let(:foo_class) do
    Class.new(described_class) do
      def double_that
        some_base_method * 2
      end
    end
  end

  it { expect(foo_class.new.double_that).to eq(4) }
end

# good - constant is stubbed
describe SomeClass do
  before do
    foo_class = Class.new(described_class) do
                  def do_something
                  end
                end
    stub_const('FooClass', foo_class)
  end

  it { expect(FooClass.new.double_that).to eq(4) }
end
# bad
describe SomeClass do
  module SomeModule
    class SomeClass
      def do_something
      end
    end
  end
end

# good
describe SomeClass do
  before do
    foo_class = Class.new(described_class) do
                  def do_something
                  end
                end
    stub_const('SomeModule::SomeClass', foo_class)
  end
end

RSpec/LetBeforeExamples

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.16

1.22

Checks for let definitions that come after an example.

Examples

# Bad
let(:foo) { bar }

it 'checks what foo does' do
  expect(foo).to be
end

let(:some) { other }

it 'checks what some does' do
  expect(some).to be
end

# Good
let(:foo) { bar }
let(:some) { other }

it 'checks what foo does' do
  expect(foo).to be
end

it 'checks what some does' do
  expect(some).to be
end

RSpec/LetSetup

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

-

Checks unreferenced let! calls being used for test setup.

Examples

# Bad
let!(:my_widget) { create(:widget) }

it 'counts widgets' do
  expect(Widget.count).to eq(1)
end

# Good
it 'counts widgets' do
  create(:widget)
  expect(Widget.count).to eq(1)
end

# Good
before { create(:widget) }

it 'counts widgets' do
  expect(Widget.count).to eq(1)
end

RSpec/MessageChain

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

-

Check that chains of messages are not being stubbed.

Examples

# bad
allow(foo).to receive_message_chain(:bar, :baz).and_return(42)

# better
thing = Thing.new(baz: 42)
allow(foo).to receive(:bar).and_return(thing)

RSpec/MessageExpectation

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

No

1.7

1.8

Checks for consistent message expectation style.

This cop can be configured in your configuration using the EnforcedStyle option and supports --auto-gen-config.

Examples

EnforcedStyle: allow

# bad
expect(foo).to receive(:bar)

# good
allow(foo).to receive(:bar)

EnforcedStyle: expect

# bad
allow(foo).to receive(:bar)

# good
expect(foo).to receive(:bar)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

allow

allow, expect

RSpec/MessageSpies

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.9

-

Checks that message expectations are set using spies.

This cop can be configured in your configuration using the EnforcedStyle option and supports --auto-gen-config.

Examples

EnforcedStyle: have_received

# bad
expect(foo).to receive(:bar)

# good
expect(foo).to have_received(:bar)

EnforcedStyle: receive

# bad
expect(foo).to have_received(:bar)

# good
expect(foo).to receive(:bar)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

have_received

have_received, receive

RSpec/MissingExampleGroupArgument

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.28

-

Checks that the first argument to an example group is not empty.

Examples

# bad
describe do
end

RSpec.describe do
end

# good
describe TestedClass do
end

describe "A feature example" do
end

RSpec/MultipleDescribes

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.0

-

Checks for multiple top-level example groups.

Multiple descriptions for the same class or module should either be nested or separated into different test files.

Examples

# bad
describe MyClass, '.do_something' do
end
describe MyClass, '.do_something_else' do
end

# good
describe MyClass do
  describe '.do_something' do
  end
  describe '.do_something_else' do
  end
end

RSpec/MultipleExpectations

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

1.21

Checks if examples contain too many expect calls.

This cop is configurable using the Max option and works with --auto-gen-config.

Examples

# bad
describe UserCreator do
  it 'builds a user' do
    expect(user.name).to eq("John")
    expect(user.age).to eq(22)
  end
end

# good
describe UserCreator do
  it 'sets the users name' do
    expect(user.name).to eq("John")
  end

  it 'sets the users age' do
    expect(user.age).to eq(22)
  end
end

configuration

# .rubocop.yml
# RSpec/MultipleExpectations:
#   Max: 2

# not flagged by rubocop
describe UserCreator do
  it 'builds a user' do
    expect(user.name).to eq("John")
    expect(user.age).to eq(22)
  end
end

Configurable attributes

Name Default value Configurable values

Max

1

Integer

RSpec/MultipleMemoizedHelpers

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.43

-

Checks if example groups contain too many let and subject calls.

This cop is configurable using the Max option and the AllowSubject which will configure the cop to only register offenses on calls to let and not calls to subject.

Examples

# bad
describe MyClass do
  let(:foo) { [] }
  let(:bar) { [] }
  let!(:baz) { [] }
  let(:qux) { [] }
  let(:quux) { [] }
  let(:quuz) { {} }
end

describe MyClass do
  let(:foo) { [] }
  let(:bar) { [] }
  let!(:baz) { [] }

  context 'when stuff' do
    let(:qux) { [] }
    let(:quux) { [] }
    let(:quuz) { {} }
  end
end

# good
describe MyClass do
  let(:bar) { [] }
  let!(:baz) { [] }
  let(:qux) { [] }
  let(:quux) { [] }
  let(:quuz) { {} }
end

describe MyClass do
  context 'when stuff' do
    let(:foo) { [] }
    let(:bar) { [] }
    let!(:booger) { [] }
  end

  context 'when other stuff' do
    let(:qux) { [] }
    let(:quux) { [] }
    let(:quuz) { {} }
  end
end

when disabling AllowSubject configuration

# rubocop.yml
# RSpec/MultipleMemoizedHelpers:
#   AllowSubject: false

# bad - `subject` counts towards memoized helpers
describe MyClass do
  subject { {} }
  let(:foo) { [] }
  let(:bar) { [] }
  let!(:baz) { [] }
  let(:qux) { [] }
  let(:quux) { [] }
end

with Max configuration

# rubocop.yml
# RSpec/MultipleMemoizedHelpers:
#   Max: 1

# bad
describe MyClass do
  let(:foo) { [] }
  let(:bar) { [] }
end

Configurable attributes

Name Default value Configurable values

AllowSubject

true

Boolean

Max

5

Integer

RSpec/MultipleSubjects

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.16

-

Checks if an example group defines subject multiple times.

The autocorrect behavior for this cop depends on the type of duplication:

  • If multiple named subjects are defined then this probably indicates that the overwritten subjects (all subjects except the last definition) are effectively being used to define helpers. In this case they are replaced with let.

  • If multiple unnamed subjects are defined though then this can only be dead code and we remove the overwritten subject definitions.

  • If subjects are defined with subject! then we don’t autocorrect. This is enough of an edge case that people can just move this to a before hook on their own

Examples

# bad
describe Foo do
  subject(:user) { User.new }
  subject(:post) { Post.new }
end

# good
describe Foo do
  let(:user) { User.new }
  subject(:post) { Post.new }
end

RSpec/NamedSubject

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.5.3

-

Checks for explicitly referenced test subjects.

RSpec lets you declare an "implicit subject" using subject { …​ } which allows for tests like it { is_expected.to be_valid }. If you need to reference your test subject you should explicitly name it using subject(:your_subject_name) { …​ }. Your test subjects should be the most important object in your tests so they deserve a descriptive name.

This cop can be configured in your configuration using the IgnoreSharedExamples which will not report offenses for implicit subjects in shared example groups.

Examples

# bad
RSpec.describe User do
  subject { described_class.new }

  it 'is valid' do
    expect(subject.valid?).to be(true)
  end
end

# good
RSpec.describe Foo do
  subject(:user) { described_class.new }

  it 'is valid' do
    expect(user.valid?).to be(true)
  end
end

# also good
RSpec.describe Foo do
  subject(:user) { described_class.new }

  it { is_expected.to be_valid }
end

Configurable attributes

Name Default value Configurable values

IgnoreSharedExamples

true

Boolean

RSpec/NestedGroups

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

1.10

Checks for nested example groups.

This cop is configurable using the Max option and supports `--auto-gen-config

Examples

# bad
context 'when using some feature' do
  let(:some)    { :various }
  let(:feature) { :setup   }

  context 'when user is signed in' do  # flagged by rubocop
    let(:user) do
      UserCreate.call(user_attributes)
    end

    let(:user_attributes) do
      {
        name: 'John',
        age:  22,
        role: role
      }
    end

    context 'when user is an admin' do # flagged by rubocop
      let(:role) { 'admin' }

      it 'blah blah'
      it 'yada yada'
    end
  end
end

# better
context 'using some feature as an admin' do
  let(:some)    { :various }
  let(:feature) { :setup   }

  let(:user) do
    UserCreate.call(
      name: 'John',
      age:  22,
      role: 'admin'
    )
  end

  it 'blah blah'
  it 'yada yada'
end

configuration

# .rubocop.yml
# RSpec/NestedGroups:
#   Max: 2

context 'when using some feature' do
  let(:some)    { :various }
  let(:feature) { :setup   }

  context 'when user is signed in' do
    let(:user) do
      UserCreate.call(user_attributes)
    end

    let(:user_attributes) do
      {
        name: 'John',
        age:  22,
        role: role
      }
    end

    context 'when user is an admin' do # flagged by rubocop
      let(:role) { 'admin' }

      it 'blah blah'
      it 'yada yada'
    end
  end
end

Configurable attributes

Name Default value Configurable values

Max

3

Integer

RSpec/NotToNot

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.4

-

Checks for consistent method usage for negating expectations.

Examples

# bad
it '...' do
  expect(false).to_not be_true
end

# good
it '...' do
  expect(false).not_to be_true
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

not_to

not_to, to_not

RSpec/OverwritingSetup

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.14

-

Checks if there is a let/subject that overwrites an existing one.

Examples

# bad
let(:foo) { bar }
let(:foo) { baz }

subject(:foo) { bar }
let(:foo) { baz }

let(:foo) { bar }
let!(:foo) { baz }

# good
subject(:test) { something }
let(:foo) { bar }
let(:baz) { baz }
let!(:other) { other }

RSpec/Pending

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

No

1.25

-

Checks for any pending or skipped examples.

Examples

# bad
describe MyClass do
  it "should be true"
end

describe MyClass do
  it "should be true", skip: true do
    expect(1).to eq(2)
  end
end

describe MyClass do
  it "should be true" do
    pending
  end
end

describe MyClass do
  xit "should be true" do
  end
end

# good
describe MyClass do
end

RSpec/PredicateMatcher

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes (Unsafe)

1.16

-

Prefer using predicate matcher over using predicate method directly.

RSpec defines magic matchers for predicate methods. This cop recommends to use the predicate matcher instead of using predicate method directly.

Examples

Strict: true, EnforcedStyle: inflected (default)

# bad
expect(foo.something?).to be_truthy

# good
expect(foo).to be_something

# also good - It checks "true" strictly.
expect(foo.something?).to be(true)

Strict: false, EnforcedStyle: inflected

# bad
expect(foo.something?).to be_truthy
expect(foo.something?).to be(true)

# good
expect(foo).to be_something

Strict: true, EnforcedStyle: explicit

# bad
expect(foo).to be_something

# good - the above code is rewritten to it by this cop
expect(foo.something?).to be(true)

Strict: false, EnforcedStyle: explicit

# bad
expect(foo).to be_something

# good - the above code is rewritten to it by this cop
expect(foo.something?).to be_truthy

Configurable attributes

Name Default value Configurable values

Strict

true

Boolean

EnforcedStyle

inflected

inflected, explicit

AllowedExplicitMatchers

[]

Array

RSpec/ReceiveCounts

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.26

-

Check for once and twice receive counts matchers usage.

Examples

# bad
expect(foo).to receive(:bar).exactly(1).times
expect(foo).to receive(:bar).exactly(2).times
expect(foo).to receive(:bar).at_least(1).times
expect(foo).to receive(:bar).at_least(2).times
expect(foo).to receive(:bar).at_most(1).times
expect(foo).to receive(:bar).at_most(2).times

# good
expect(foo).to receive(:bar).once
expect(foo).to receive(:bar).twice
expect(foo).to receive(:bar).at_least(:once)
expect(foo).to receive(:bar).at_least(:twice)
expect(foo).to receive(:bar).at_most(:once)
expect(foo).to receive(:bar).at_most(:twice).times

RSpec/ReceiveNever

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.28

-

Prefer not_to receive(…​) over receive(…​).never.

Examples

# bad
expect(foo).to receive(:bar).never

# good
expect(foo).not_to receive(:bar)

RSpec/RepeatedDescription

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.9

-

Check for repeated description strings in example groups.

Examples

# bad
RSpec.describe User do
  it 'is valid' do
    # ...
  end

  it 'is valid' do
    # ...
  end
end

# good
RSpec.describe User do
  it 'is valid when first and last name are present' do
    # ...
  end

  it 'is valid when last name only is present' do
    # ...
  end
end

# good
RSpec.describe User do
  it 'is valid' do
    # ...
  end

  it 'is valid', :flag do
    # ...
  end
end

RSpec/RepeatedExample

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.10

-

Check for repeated examples within example groups.

Examples

it 'is valid' do
  expect(user).to be_valid
end

it 'validates the user' do
  expect(user).to be_valid
end

RSpec/RepeatedExampleGroupBody

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.38

-

Check for repeated describe and context block body.

Examples

# bad
describe 'cool feature x' do
  it { cool_predicate }
end

describe 'cool feature y' do
  it { cool_predicate }
end

# good
describe 'cool feature' do
  it { cool_predicate }
end

describe 'another cool feature' do
  it { another_predicate }
end

# good
context 'when case x', :tag do
  it { cool_predicate }
end

context 'when case y' do
  it { cool_predicate }
end

# good
context Array do
  it { is_expected.to respond_to :each }
end

context Hash do
  it { is_expected.to respond_to :each }
end

RSpec/RepeatedExampleGroupDescription

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.38

-

Check for repeated example group descriptions.

Examples

# bad
describe 'cool feature' do
  # example group
end

describe 'cool feature' do
  # example group
end

# bad
context 'when case x' do
  # example group
end

describe 'when case x' do
  # example group
end

# good
describe 'cool feature' do
  # example group
end

describe 'another cool feature' do
  # example group
end

# good
context 'when case x' do
  # example group
end

context 'when another case' do
  # example group
end

RSpec/RepeatedIncludeExample

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.44

-

Check for repeated include of shared examples.

Examples

# bad
describe 'foo' do
  include_examples 'cool stuff'
  include_examples 'cool stuff'
end

# bad
describe 'foo' do
  it_behaves_like 'a cool', 'thing'
  it_behaves_like 'a cool', 'thing'
end

# bad
context 'foo' do
  it_should_behave_like 'a duck'
  it_should_behave_like 'a duck'
end

# good
describe 'foo' do
  include_examples 'cool stuff'
end

describe 'bar' do
  include_examples 'cool stuff'
end

# good
describe 'foo' do
  it_behaves_like 'a cool', 'thing'
  it_behaves_like 'a cool', 'person'
end

# good
context 'foo' do
  it_should_behave_like 'a duck'
  it_should_behave_like 'a goose'
end

RSpec/ReturnFromStub

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.16

1.22

Checks for consistent style of stub’s return setting.

Enforces either and_return or block-style return in the cases where the returned value is constant. Ignores dynamic returned values are the result would be different

This cop can be configured using the EnforcedStyle option

Examples

EnforcedStyle: block

# bad
allow(Foo).to receive(:bar).and_return("baz")
expect(Foo).to receive(:bar).and_return("baz")

# good
allow(Foo).to receive(:bar) { "baz" }
expect(Foo).to receive(:bar) { "baz" }
# also good as the returned value is dynamic
allow(Foo).to receive(:bar).and_return(bar.baz)

EnforcedStyle: and_return

# bad
allow(Foo).to receive(:bar) { "baz" }
expect(Foo).to receive(:bar) { "baz" }

# good
allow(Foo).to receive(:bar).and_return("baz")
expect(Foo).to receive(:bar).and_return("baz")
# also good as the returned value is dynamic
allow(Foo).to receive(:bar) { bar.baz }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

and_return

and_return, block

RSpec/ScatteredLet

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.14

1.39

Checks for let scattered across the example group.

Group lets together

Examples

# bad
describe Foo do
  let(:foo) { 1 }
  subject { Foo }
  let(:bar) { 2 }
  before { prepare }
  let!(:baz) { 3 }
end

# good
describe Foo do
  subject { Foo }
  before { prepare }
  let(:foo) { 1 }
  let(:bar) { 2 }
  let!(:baz) { 3 }
end

RSpec/ScatteredSetup

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.10

-

Checks for setup scattered across multiple hooks in an example group.

Unify before, after, and around hooks when possible.

Examples

# bad
describe Foo do
  before { setup1 }
  before { setup2 }
end

# good
describe Foo do
  before do
    setup1
    setup2
  end
end

RSpec/SharedContext

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.13

-

Checks for proper shared_context and shared_examples usage.

If there are no examples defined, use shared_context. If there is no setup defined, use shared_examples.

Examples

# bad
RSpec.shared_context 'only examples here' do
  it 'does x' do
  end

  it 'does y' do
  end
end

# good
RSpec.shared_examples 'only examples here' do
  it 'does x' do
  end

  it 'does y' do
  end
end
# bad
RSpec.shared_examples 'only setup here' do
  subject(:foo) { :bar }

  let(:baz) { :bazz }

  before do
    something
  end
end

# good
RSpec.shared_context 'only setup here' do
  subject(:foo) { :bar }

  let(:baz) { :bazz }

  before do
    something
  end
end

RSpec/SharedExamples

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.25

-

Enforces use of string to titleize shared examples.

Examples

# bad
it_behaves_like :foo_bar_baz
it_should_behave_like :foo_bar_baz
shared_examples :foo_bar_baz
shared_examples_for :foo_bar_baz
include_examples :foo_bar_baz

# good
it_behaves_like 'foo bar baz'
it_should_behave_like 'foo bar baz'
shared_examples 'foo bar baz'
shared_examples_for 'foo bar baz'
include_examples 'foo bar baz'

RSpec/SingleArgumentMessageChain

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.9

1.10

Checks that chains of messages contain more than one element.

Examples

# bad
allow(foo).to receive_message_chain(:bar).and_return(42)

# good
allow(foo).to receive(:bar).and_return(42)

# also good
allow(foo).to receive(:bar, :baz)
allow(foo).to receive("bar.baz")

RSpec/StubbedMock

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Pending

Yes

No

1.44

-

Checks that message expectations do not have a configured response.

Examples

# bad
expect(foo).to receive(:bar).with(42).and_return("hello world")

# good (without spies)
allow(foo).to receive(:bar).with(42).and_return("hello world")
expect(foo).to receive(:bar).with(42)

RSpec/SubjectStub

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.7

-

Checks for stubbed test subjects.

Examples

# bad
describe Foo do
  subject(:bar) { baz }

  before do
    allow(bar).to receive(:qux?).and_return(true)
  end
end

RSpec/UnspecifiedException

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.30

-

Checks for a specified error in checking raised errors.

Enforces one of an Exception type, a string, or a regular expression to match against the exception message as a parameter to raise_error

Examples

# bad
expect {
  raise StandardError.new('error')
}.to raise_error

# good
expect {
  raise StandardError.new('error')
}.to raise_error(StandardError)

expect {
  raise StandardError.new('error')
}.to raise_error('error')

expect {
  raise StandardError.new('error')
}.to raise_error(/err/)

expect { do_something }.not_to raise_error

RSpec/VariableDefinition

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.40

-

Checks that memoized helpers names are symbols or strings.

Examples

EnforcedStyle: symbols (default)

# bad
subject('user') { create_user }
let('user_name') { 'Adam' }

# good
subject(:user) { create_user }
let(:user_name) { 'Adam' }

EnforcedStyle: strings

# bad
subject(:user) { create_user }
let(:user_name) { 'Adam' }

# good
subject('user') { create_user }
let('user_name') { 'Adam' }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

symbols

symbols, strings

RSpec/VariableName

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.40

1.43

Checks that memoized helper names use the configured style.

Variables can be excluded from checking using the IgnoredPatterns option.

Examples

EnforcedStyle: snake_case (default)

# bad
subject(:userName1) { 'Adam' }
let(:userName2) { 'Adam' }

# good
subject(:user_name_1) { 'Adam' }
let(:user_name_2) { 'Adam' }

EnforcedStyle: camelCase

# bad
subject(:user_name_1) { 'Adam' }
let(:user_name_2) { 'Adam' }

# good
subject(:userName1) { 'Adam' }
let(:userName2) { 'Adam' }

IgnoredPatterns configuration

# rubocop.yml
# RSpec/VariableName:
#   EnforcedStyle: snake_case
#   IgnoredPatterns:
#     - ^userFood
# okay because it matches the `^userFood` regex in `IgnoredPatterns`
subject(:userFood_1) { 'spaghetti' }
let(:userFood_2) { 'fettuccine' }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

snake_case

snake_case, camelCase

IgnoredPatterns

[]

Array

RSpec/VerifiedDoubles

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.2.1

1.5

Prefer using verifying doubles over normal doubles.

Examples

# bad
let(:foo) do
  double(method_name: 'returned value')
end

# bad
let(:foo) do
  double("ClassName", method_name: 'returned value')
end

# good
let(:foo) do
  instance_double("ClassName", method_name: 'returned value')
end

Configurable attributes

Name Default value Configurable values

IgnoreNameless

true

Boolean

IgnoreSymbolicNames

false

Boolean

RSpec/VoidExpect

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

1.16

-

This cop checks void expect().

Examples

# bad
expect(something)

# good
expect(something).to be(1)

RSpec/Yield

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

1.32

-

This cop checks for calling a block within a stub.

Examples

# bad
allow(foo).to receive(:bar) { |&block| block.call(1) }

# good
expect(foo).to be(:bar).and_yield(1)