0

我正在使用模拟来测试我开发的东西。在应用程序中,我使用glob循环查找目录中的某些内容,例如:'/tmp/*.png'。它将收集目录中的所有 .png 文件并返回该文件的列表。

当我模拟 glob 时,它会返回调用。然而,当用于循环时它并不顺利for

#stack.py
import os
import click
import hashlib
import glob

def bar(x):
    return os.path.basename(x)

def foo(path):
    images = glob.glob(path)
    for i in images:
        bar(i)


if __name__ == '__main__':
    foo()

#test_stack.py
import os
import unittest
import mock
import tempfile
import stack


class StackTest(unittest.TestCase):

    temp_dir = tempfile.gettempdir()
    temp_rg3 = os.path.join(temp_dir, "testfile.rg3")

    @mock.patch('stack.os')
    @mock.patch('stack.hashlib')
    @mock.patch('stack.glob')
    def test_stack(self, mock_glob, mock_hashlib, mock_os):
        stack.foo(self.temp_rg3)

        print(mock_glob.method_calls)
        print(mock_os.method_calls)

这是回报:

[call.glob('/tmp/testfile.rg3')]
[]
[]

在 glob 被调用后,glob.glob(path)它的返回值不会反映images. 因此 for 循环不会开始bar(i)也不会被调用,因此mock_os不会返回任何调用。

4

1 回答 1

1

如果我理解您的问题,您似乎没有为您的模拟设置返回值。

当您生成一个 MagicMock 对象时,它的默认返回值是模拟实例本身,如此所述。此实例不是迭代器,因此在被 for 循环迭代时不会做任何事情。

您可以提供如下返回值,将您的模拟更改为您正在调用的特定函数:

@mock.patch('stack.os')
@mock.patch('stack.hashlib')
@mock.patch('stack.glob.glob', return_value=['a.png', 'b.png', 'c.png'])
def test_stack(self, mock_glob, mock_hashlib, mock_os):
    stack.foo(self.temp_rg3)

    print(mock_glob.method_calls)
    print(mock_os.method_calls)
于 2020-03-24T12:27:17.900 回答