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.
