Python mock启动整个程序,而不是将输入替换为特定方法

时间:2017-12-30 01:11:01

标签: python unit-testing mocking python-unittest raw-input

我有一个程序,比如:

模块" Main":

import SymbolCalculator as sc


# Defining constants:
TEXT_INTRO = sc.TEXT_INTRO
TEXT_INVITE = "Please print any sentence below:\n"
sentence = ""
# Printing introduction to the program:
print TEXT_INTRO

def getting_result():
    # Getting input string from console
    sentence = sc.get_input_from_prompt(TEXT_INVITE)
    # Forming result list via methods defined in SymbolCalculator module
    return sc.characters_calculator(sentence)
result_list = getting_result()
# Computing summary via method defined in SymbolCalculator module
sc.printing_summary(sentence, result_list)
# Printing tuples with characters and their occurrences raw-by-raw
sc.printing_list(result_list)
raw_input("Please press any button to quit the program.")
print 'Bye!!!'

我试图使用模拟的raw_input创建一个简单的单元测试(更新):

from unittest import TestCase, main
from mock import patch
from Ex_41_42_SymbolCalculatorMain import getting_result


class Ex_4a1_SymbolCalculatorUnitTestWMock(TestCase):
    #@patch ('Ex_41_42_SymbolCalculator.get_input_from_prompt', return_value = 'aabc')
    def test_valid_input(self):
        with patch('__builtin__.raw_input', return_value = 'aaabbc') as _raw_input:
            self.assertEqual(getting_result(), [('a', 3), ('b', 2), ('c', 1)])
            _raw_input.assert_called_once_with('Please print any sentence below:\n')

    @patch ('Ex_41_42_SymbolCalculator.get_input_from_prompt', return_value = '')
    def test_empty_input(self, mock):
        self.assertEqual(getting_result(), [])

if __name__ == "__main__":
    main()

我也尝试通过自己的测试方法来装饰,例如:

...
@patch ('Ex_41_42_SymbolCalculator.get_input_from_prompt', return_value = 'aabc')
...

我的问题是,当我启动测试时,所有" Main"模块在getting_result方法调用时运行。所以它从一开始就要求我通过命令提示符等进行输入。这样不仅可以测试,而且整个常规程序都在运行。

虽然我预计getting_result只会调用return_value方法。

请告知。

1 个答案:

答案 0 :(得分:1)

导入模块时,将运行模块中的所有代码。使用from Ex_41_42_SymbolCalculatorMain import getting_result代替import Ex_41_42_SymbolCalculatorMain并不重要;你还在导入模块。没有办法只是"得到"一个函数没有执行模块中的其余代码。

相反,您应该将该代码放在一个函数中,然后在if __name__ == "__main__"块中调用它,如下所示:

def getting_result():
    # Getting input string from console
    sentence = sc.get_input_from_prompt(TEXT_INVITE)
    # Forming result list via methods defined in SymbolCalculator module
    return sc.characters_calculator(sentence)

def do_stuff():
    print TEXT_INTRO
    result_list = getting_result()
    # Computing summary via method defined in SymbolCalculator module
    sc.printing_summary(sentence, result_list)
    # Printing tuples with characters and their occurrences raw-by-raw
    sc.printing_list(result_list)
    raw_input("Please press any button to quit the program.")
    print 'Bye!!!'

if __name__ == "__main__":
    do_stuff()

然后只有在您直接执行该文件时才会运行do_stuff(),而不是导入它。这将允许您导入模块而不运行do_stuff中的内容。您可以通过在此网站上搜索有关它的数以万计的问题(例如this one)来详细了解__main__业务。