1

I am testing this method:

  def get_input
    print "Pick a column (0-6):\n"
    valid_input?(gets) || get_input
  end

How can i test if the get_input method is called from inside itself? because if i use

describe '#get_input' do
    subject(:game_input) { described_class.new(1, 2) }
    it 'sends get_input when input is invalid' do
      allow(game_input).to receive(:valid_input?).and_return(false)
      expect(game_input).to receive(:get_input)
      game_input.get_input
  end

it passes the test regardless since get_input is called first anyways.

I want to test if get_input is called from within itself, and not continue looping when i give it an invalid input in the test.

Something like:

I set valid_input? to return false in my test
I check if get_input is called on game_input, but only from inside the get_input method

Any help is appreciated

Also im completely new to RSpec so sorry for any stupid questions

Skauen
  • 11
  • 1
  • You'd likely want to check the number of times `get_input` is called (and provide enough return values for `valid_input?` to match). Unrelated, but a recursive function like this, while clean, isn't necessarily the best approach; IRL it's just a way for someone to crash the game. – Dave Newton Sep 16 '21 at 12:42
  • Something like this? `it 'sends get_input when input is invalid' do allow(game_input).to receive(:valid_input?).and_return(false, true) expect(game_input).to receive(:valid_input?).twice game_input.get_input end` also thanks for the tip, should i use a loop instead? – Skauen Sep 16 '21 at 12:47
  • You could also check out the `Kernel#caller` https://stackoverflow.com/a/5100339/7619578 , https://apidock.com/ruby/Kernel/caller , https://reinteractive.com/posts/399-dissecting-code-with-ruby-s-caller-method – Int'l Man Of Coding Mystery Sep 16 '21 at 13:14
  • @Skauen I don't recall the exact syntax, but that's the right idea. *I* would use a loop, but that doesn't mean it's right ;) – Dave Newton Sep 16 '21 at 13:20
  • Isn’t the recursion an implementation detail? The method could achieve the same behavior with a loop. Maybe you can find a more robust approach to test your method if you don’t focus on the recursion. – Stefan Sep 16 '21 at 20:35
  • @Stefan I acutally started with a loop, but thought it would be easier to test if `get_input` was sent again, rather than testing the loop (again, im new to this). But i can see how recursion can cause the app to crash if someone tries. – Skauen Sep 17 '21 at 09:39
  • With _"more robust approach"_ I mean the test. Instead of checking for recursion you could check whether the user is prompted again after providing invalid input. This way, you'd test the method's behavior instead of its implementation. – Stefan Sep 17 '21 at 09:53
  • @Stefan Thats what I ended up doing. Makes more sense now. – Skauen Sep 20 '21 at 06:42

0 Answers0