Python mock / unittest:你如何模拟一个类成员?

时间:2018-04-19 14:45:36

标签: python-2.7 for-loop python-unittest python-mock

我正在尝试对读取requirements.txt文件的脚本进行单元测试,并通过pip遍历每一行安装它。然而,我的单元测试它似乎没有进入循环,因为self.requirements是空的。我尝试将它设置为['foobar']的self.setupvirtualenv.requirements但是这不起作用。

我的问题是如何模拟self.requirements列表以便它进入for循环并调用subprocess.call?

def install_requirements(self):
    self.requirements = open(self.requirements_path, 'r').readlines()
    for req in self.requirements:
        req = req.strip()
        pip_command = r'pip install {}'.format(req)
        subprocess.call(pip_command, shell=True)

我的单元测试:

import setupvirualenv
import unittest
from mock import patch, Mock

def test_install_requirements(self, mock_open, mock_subprocess_call):
    self.setupvirtualenv.requirements = ['foobar']
    self.setupvirtualenv.install_requirements()
    mock_open.assert_called_once_with('foobar', 'r')
    mock_subprocess_call.assert_called_once() 

失败消息

AssertionError: Expected 'call' to have been called once. Called 0 times.

1 个答案:

答案 0 :(得分:0)

您应该模拟open调用,以便readlines()返回虚拟数据。

看起来好像你可能缺少测试方法中的patch装饰器。我已经在下面列出了它们应该是什么样的。

from mock import patch

@patch('setupvirtualenv.subprocess.call')
@patch('setupvirtualenv.open')
def test_install_requirements(self, mock_open, mock_subprocess_call):
    # Mock the call to open() and the return value from readlines()
    mock_open.return_value.readlines.return_value = ['foobar\n']
    self.setupvirtualenv.install_requirements()
    mock_open.assert_called_once_with('foobar', 'r')
    mock_subprocess_call.assert_called_once()