模拟与__init__.py模块混淆

时间:2018-04-16 23:15:35

标签: python unit-testing mocking python-unittest

我目前正在尝试使用mock来测试一个包。当我使用__init__.py

在不同的目录中构建我的python模块时,Mock似乎不喜欢它

我的文件树如下:

.\pkg
  |_ module
       |_ __init__.py
       |_ module.py
  |_ tests
       |_ __init__.py
       |_ test_basic.py

当我尝试使用以下单元测试来模拟filesize中的方法时:

@mock.patch('module.os')
def test_filesize(self, mock_os):
    class file_info:
        st_size = 1000

    mock_os.path.isfile.return_value = True
    mock_os.stat.return_value = file_info

    output = self.response.file_size("filename")

我收到错误的跟踪:

======================================================================
ERROR: test_filesize (__main__.cl_test_build_search_url)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\mock\mock.py", line 1297, in patched
    arg = patching.__enter__()
  File "C:\Python36\lib\site-packages\mock\mock.py", line 1369, in __enter__
    original, local = self.get_original()
  File "C:\Python36\lib\site-packages\mock\mock.py", line 1343, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <module 'module' from 'C:\\Users\\username\\work\\open_source\\pkg\\module\\__init__.py'> does not have the attribute 'os'

我已经在module.py中导入了os模块但是我觉得它很混乱,因为__init__.py让解释器感到困惑?

我查看了可用的mock.patch参数和

@mock.patch('module.os', create = True)

允许代码运行但是os根本不会被模拟,os.path.isfile并且os.stat在运行时不会被覆盖。

1 个答案:

答案 0 :(得分:1)

尝试改变这一点:

@mock.patch('module.os', create = True)

到此:

# module(directory) module(module.py)
@mock.patch('module.module.os', create = True)

我不擅长解释,这是mock.py的摘要解释:

  

target应为'package.module.ClassName'形式的字符串。该       导入target并将指定的对象替换为new       对象,因此target必须可以从您所处的环境中导入       从中调用patch。目标是在装饰函数时导入的       是在执行时执行,而不是在装修时执行。