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.