I am trying to test if an instance variable saves input from user but I cant figure out how. I expect the test to pass but it fails and outputs expected "joe" got: ""
to the terminal. Here is the method, I want to test:
def get_names
while Player.players < 2
while name.length <= 2
puts 'Each player must choose a name'
print 'Enter a name: '
@name = gets.chomp
end
unless name == ''
@player1 == '' ? @player1 = Player.new(name) : @player2 = Player.new(name)
name = ''
puts 'Name have been saved successfully'
end
end
end
And here is the rspec test suite:
describe Game do
subject(:game_names) { described_class.new }
describe '#get_names' do
context 'when a user inputs name' do
it 'saves in name instance variable' do
allow(game_names).to receive(:gets).and_return('joe')
name = game_names.instance_variable_get(:@name)
expect(name).to eq 'joe'
game_names.get_names
end
end
end
end
I gave tried mocking and stubbing the class, the method and the variable, but I can't get it to work. This is my first time writing tests.
CodePudding user response:
Without knowing what the rest of your Game
and Player
classes look like. I would say that you may have an execution order problem in your tests. I am basing the following on the assumption that you might not have a @name
instance variable in your initialize
method.
So in your tests, you're stubbing the call to gets
and returning 'joe'
which is cool and exactly what you want. But the next line after that goes and gets the instance variable @name
which doesn't exist in the class at that moment because the method which sets that instance variable up hasn't been called yet. And undeclared instance variables will always hold the value, nil
.
So you're essentially comparing nil
to 'joe'
which will never pass.
What you want to do is move game_names.get_names
under the allow
followed by the instance_variable_get
line, and lastly the expect
assertion.
describe Game do
subject(:game_names) { described_class.new }
describe '#get_names' do
context 'when a user inputs name' do
it 'saves in name instance variable' do
allow(game_names).to receive(:gets).and_return('joe')
game_names.get_names
name = game_names.instance_variable_get(:@name)
expect(name).to eq 'joe'
end
end
end
end
CodePudding user response:
The bug was in the name
assignment to empty string after saving input, so I commented it out and the test passed.