使用mock从导入的文件修补导入的open

时间:2014-09-05 22:33:33

标签: python mocking

我有两个文件:

#file1.py
def_writefile():
    ...
    fp = open('file')
    fp.write('blah')
    ...


#file2.py
file1.writefile()

我尝试以不同方式修补:

#test_file.py
fn = mock.mock_open()
with mock.patch('__builtin__.open', fn):
    file1.writefile()

with mock.patch('file1.open', fn):
    file1.writefile()

with mock.patch('file2.open', fn):
    file1.writefile()

with mock.patch('__main__.open', fn, create=True):
    file1.writefile()

assert(mock_file().write.called_once_with('blah'))

但它们似乎都不起作用。使用mock从导入的模块中修补内置结构的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

你想要这个:

import file1

fn = mock.mock_open()
with mock.patch('file1.open', fn, create=True):
    file1.writefile()

fn().write.assert_called_once_with('blah')

您需要模拟将在open中使用的file1.py函数,因此我们通过'file1.open'而不是'__main__.open'。您遗失的另一件事是,您没有使用正确的功能来确保使用正确的参数调用write - 您需要使用构建的assert_called_once_with函数进入Mock课程。

create=True是必需的,因为在导入时open课程中找不到file1函数,因为open函数赢了\ t实际上被拉入模块直到运行时。通常,这意味着mock会抛出异常,说file1缺少该属性。添加create=True会使mock在找不到属性时创建该属性,并且mentioned in the docs对此情况有用:

  

这对于编写针对您的属性的测试非常有用   生产代码在运行时创建