I have this function that asks the user for the gender of the voice and then reads the text in that voice. If the user input is not either male or female it raises a value error. I want to write a unit test for this function, but don't know how exactly I can do that.
def pdftospeech(n):
readersvoice = input("Voice: ").lower().strip()
voices = engine.getProperty("voices")
if readersvoice == "female":
engine.setProperty("voice", voices[1].id)
elif readersvoice == "male":
engine.setProperty("voice", voices[0].id)
else:
raise ValueError("Choose from male or female")
engine.setProperty("rate", 150)
rate = engine.getProperty("rate")
engine.say(n)
engine.runAndWait()
CodePudding user response:
My recommendation would be to split out the asking and checking of input from the getting and setting of properties on the engine.
For example:
def ask_voice():
readers_voice = input("Voice: ").lower().strip()
if readers_voice not in ["female", "male"]:
raise ValueError("Choose from male or female")
return readers_voice
def read_with_voice(n, readers_voice):
voices = engine.getProperty("voices")
if readers_voice == "female":
engine.setProperty("voice", voices[1].id)
elif readers_voice == "male":
engine.setProperty("voice", voices[0].id)
engine.setProperty("rate", 150)
rate = engine.getProperty("rate")
engine.say(n)
engine.runAndWait()
def pdftospeech(n):
readers_voice = ask_voice()
read_with_voice(n, readers_voice)
The test for ask_voice
is then more straightforward:
import unittest
from unittest import mock
def ask_voice():
readers_voice = input("Voice: ").lower().strip()
if readers_voice not in ["female", "male"]:
raise ValueError("Choose from male or female")
return readers_voice
class Test101(unittest.TestCase):
def test_ask_male(self):
with mock.patch('builtins.input', return_value="MaLe"):
self.assertEqual('male', ask_voice())
def test_ask_female(self):
with mock.patch('builtins.input', return_value="FeMaLe"):
self.assertEqual('female', ask_voice())
def test_ask_fail(self):
with mock.patch('builtins.input', return_value="mail"):
self.assertRaises(ValueError, ask_voice)
if __name__ == '__main__':
unittest.main(verbosity=2)
This test gave the following output:
test_ask_fail (__main__.Test101) ... ok
test_ask_female (__main__.Test101) ... ok
test_ask_male (__main__.Test101) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK