-1

I am writing a program in python and one of my methods should take in a string, and if that string is not of desired length, I want it to raise an exception and pass the corresponding unittest without throwing errors in the console.

Method:

def validate_length(guess):.
  
  if len(guess) != 5:
      raise Exception("Invalid guess length")

Unittest:

  @parameterized.expand([
    ("FOR"),
    ("FERVER"),
  ])
  def test_for_wrong_word_length(self, guess):
    self.assertRaises(Exception, tally("FAVOR", guess))

Output:

Exception: Invalid guess length
Exception: Invalid guess length

FAILED (errors=2)

I want this to give me the status 'OK' rather than 'FAILED (errors=2).' Everything I have read on unittest documentation shows that it should pass this way, but I can't figure out why.

Also, I have my files set up correctly and imports, etc. These blocks above are just snippets. I have other tests working properly.

Ethan
  • 39
  • 5
  • 1
    Because the error is thrown before assertRaises gets called... – jonrsharpe Feb 17 '23 at 16:21
  • @jonrsharpe can you expand more on "Because the error is thrown before assertRaises gets called."? – Ethan Feb 17 '23 at 16:28
  • 1
    The return value of the function has to be resolved _before_ it can be passed to the method. Think about it, assigning the result of calling `tally` to a temporary variable then passing its value you the method would be a trivial refactor. See e.g. https://stackoverflow.com/q/129507/3001761, or use the context manager method shown in the docs. – jonrsharpe Feb 17 '23 at 16:31
  • @jonrsharpe Currently, the validate_length(guess) is being called inside of the tally method. It also still fails with the same errors if I call validate_length(guess) inside of the assertRaises() test – Ethan Feb 17 '23 at 16:35
  • 1
    ...and for the same reason, presumably, but without a [mre] this is an educated guess. Please do the research, there's also e.g. https://stackoverflow.com/q/3877134/3001761. – jonrsharpe Feb 17 '23 at 16:38
  • 1
    This shows how to pass the args to assertRaises so it can call the function at the correct time. Not BEFORE you even enter assertRaises. https://stackoverflow.com/a/129610/1766544 There's also "with" but I don't find that on a quick search of SO. – Kenny Ostrom Feb 17 '23 at 16:38
  • 1
    Ah the context manager example is in the link jonrsharpe provided as one of the lower ranked answers https://stackoverflow.com/a/45544391/1766544 – Kenny Ostrom Feb 17 '23 at 16:42

1 Answers1

0
@parameterized.expand([
    ("FOR"),
    ("FERVER"),
])
def test_for_wrong_word_length(self, guess):
    with self.assertRaises(Exception) as context:
        tally("FAVOR", guess)

Needed to use context manager

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Ethan
  • 39
  • 5