rubocop-rspec magic: Fixing RSpec/InstanceVariable

We recently introduced RSpec/InstanceVariable into our RuboCop configuration at Vox Pupuli. Using instance variables is not considered best practice so we are currently migrating away from them. Here is en example of the old code style:

  before :each do
    @resource = Puppet::Type.type(:package).new(
      name: 'express',
      ensure: :present
    )
    @provider = described_class.new(@resource)
    @provider.class.stubs(:optional_commands).with(:npm).returns '/usr/local/bin/npm'
    @provider.class.stubs(:command).with(:npm).returns '/usr/local/bin/npm'
  end

The variables are later used, for example:

it 'should use package name by default' do
  @provider.expects(:npm).with('install', '--global', 'express')
  @provider.install
end

or:

it 'should use the source instead of the gem name' do
  @resource[:source] = '/tmp/express.tar.gz'
  @provider.expects(:npm).with('install', '--global', '/tmp/express.tar.gz')
  @provider.install
end

The whole spec file can be seen here, the failing tests are documented here. I was digging around a bit, but didn’t really had a clue how to fix it. Dominic Cleal was so kind to provide a fix (the following replaces the :each block):

let :resource do
  Puppet::Type.type(:package).new(
    name: 'express',
    ensure: :present
  )
end

let :provider do
  described_class.new(resource).tap do |provider|
    provider.class.stubs(:optional_commands).with(:npm).returns '/usr/local/bin/npm'
    provider.class.stubs(:command).with(:npm).returns '/usr/local/bin/npm'
  end
end

This allows us to access provider and resource as normal variables in the rest of the spec test. The fixed version is available here.

This entry was posted in General, Linux, Puppet. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.