AttributeError: None 没有属性“打印”

Sal*_*dec 5 python unit-testing function

所以我正在练习一些单元测试,我正在尝试检查 For 循环内的输出。这是我的运行代码

def main():

  for i in range(100):
    print("Argh!")
Run Code Online (Sandbox Code Playgroud)

非常基本,现在这是我的测试代码。

import unittest
from unittest import mock  # possibly "from unittest import mock" depending on version.
from RunFile import main

class TestMain(unittest.TestCase):
    def test_main(self):
        with mock.patch.object(main(), 'print') as mock_print:
            main()
        expected_calls = [mock.call('Argh!') for _ in range(100)]
        mock_print.assert_has_calls(expected_calls)

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

这是我返回的错误消息。我不确定如何解决这个问题。更新:这是完整的追溯

======================================================================
ERROR: test_main (__main__.TestMain)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Users/jsalce/Documents/Testsuites/IfStatements/Testsuite.py", line 9, in test_main
    with mock.patch.object(RunFile, 'print') as mock_print:
  File "C:\Python33\lib\unittest\mock.py", line 1148, in __enter__
    original, local = self.get_original()
  File "C:\Python33\lib\unittest\mock.py", line 1122, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <module 'RunFile' from      'C:\\Users\\jsalce\\Documents\\Testsuites\\IfStatements\\RunFile.py'> does not have the attribute 'print'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
Run Code Online (Sandbox Code Playgroud)

谢谢大家!

mgi*_*son 3

一般来说,对于mock.patch.object,您想要修补一些您可以轻松处理的东西——例如模块或类。通常,您需要修补比要替换的内容高一级的内容。例如,如果您想修补foo模块中的功能bar,那么您需要mock.patch.object(bar, 'foo').

在您的情况下,从技术上讲,print是 a builtin,但您可以在使用它的模块上修补它。这将添加一个RunFile.print“方法”(实际上是一个模拟),您可以测试断言。显然,由于print模块上实际上并不存在,因此我们需要添加create=True来告诉mock创建RunFile.print,因为它尚不存在。考虑到这一点,我将单元测试重写为:

import RunFile

class TestMain(unittest.TestCase):
    def test_main(self):
        with mock.patch.object(RunFile, 'print', create=True) as mock_print:
            RunFile.main()
        expected_calls = [mock.call('Argh!') for _ in range(100)]
        mock_print.assert_has_calls(expected_calls)

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)