Home > Net >  Mock wrong input so that pytest catches ValueError
Mock wrong input so that pytest catches ValueError

Time:09-17

I'm working on a project and I need to test my functions. I'm struggling with this one:

def name():
    # Remember user's name
    while True:
        try:
            un = str(input("What's your name? "))
            if not un.isalpha():
                raise ValueError("Please enter a valid name.")
        except ValueError:
            continue
        break
    return un.capitalize()

I was able to mock an input to check the correctness of the function, but I can't seem to catch the error raised if something like "123" is input.

This is what I've written so far:

@mock.patch("project.input", return_value = "sol")
def test_name(self):
    actual_result = name()
    expected_result = "Sol"
    assert expected_result == actual_result


@mock.patch("project.input", return_value = "123", side_effect = ValueError)
def test_name_incorrect(self):
    with pytest.raises(ValueError, match="Please enter a valid name.") as e:
        result = name()
    assert str(e.value) == "Please enter a valid name."

"test_name" works, but "test_name_incorrect" doesn't, I even have to abort it with ctrl c.

Terminal message after keyboard interruption

Can anyone help me understand what I'm doing wrong?

Thanks!!!

CodePudding user response:

The function name does not actually raise ValueError outside of its own scope, it catches the error raised in the try block and continues on the while loop. When you call name() in test_name_incorrect, the name function will loop indefinitely since a valid input is never received.

What you can do is create a separate function just for the validation that takes a string argument and raises an error if invalid, and test that separately.

See: How to test if the right exception is raised and caught using unit testing?

Could also look at the capsys fixture from pytest, if the above method is not preferred.

  • Related