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.
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.
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
RSpec/AroundBlock
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.11 |
- |
Checks that around blocks actually run the test.
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.
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
RSpec/ContextMethod
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
Yes |
1.36 |
- |
context should not be used for specifying methods.
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.
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
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.
RSpec/DescribeSymbol
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.15 |
- |
Avoid describing symbols.
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
RSpec/DescribedClassModuleWrapping
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:
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
RSpec/EmptyHook
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
Yes |
1.39 |
- |
Checks for empty before and after hooks.
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
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.
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.
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
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.
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
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
RSpec/ExpectActual
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
Yes |
1.7 |
- |
Checks for expect(…) calls containing literal values.
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 }
RSpec/ExpectInHook
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.16 |
- |
Do not use expect in hooks such as before.
RSpec/ExpectOutput
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.10 |
- |
Checks for opportunities to use expect { … }.to output.
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'
RSpec/Focus
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
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.
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.
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.
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
RSpec/InstanceSpy
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
Yes |
1.12 |
- |
Checks for instance_double used with have_received.
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
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.
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
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.
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.
RSpec/MessageChain
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.7 |
- |
Check that chains of messages are not being stubbed.
RSpec/MessageExpectation
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
RSpec/MissingExampleGroupArgument
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.
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.
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
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 abeforehook on their own
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
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
RSpec/NotToNot
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.
RSpec/Pending
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Disabled |
Yes |
No |
1.25 |
- |
Checks for any pending or skipped examples.
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
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.
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
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
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
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.
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.
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.
RSpec/SubjectStub
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
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' }
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
RSpec/VoidExpect
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged |
|---|---|---|---|---|
Enabled |
Yes |
No |
1.16 |
- |
This cop checks void expect().