Python:构建模拟函数的问题

Python: issue with building mock function

我正在编写单元测试来验证我的项目功能。我需要用模拟函数替换一些函数,我想使用 Python 模拟库。我使用的实现似乎不能正常工作,但我不明白我哪里做错了。这是一个简化的场景:

root/connector.py

from ftp_utils.py import *

def main():
    config = yaml.safe_load("vendor_sftp.yaml")
    downloaded_files = []

    downloaded_files = get_files(config)
    for f in downloaded_files:
      #do something

root/utils/ftp_utils.py

import os
import sys
import pysftp

def get_files(config):
   sftp = pysftp.Connection(config['host'], username=config['username'])
   sftp.chdir(config['remote_dir'])
   down_files = sftp.listdir()
   if down_files is not None:
     for f in down_files:
       sftp.get(f, os.path.join(config['local_dir'], f), preserve_mtime=True)

   return down_files

root/tests/connector_tester.py

import unittest
import mock
import ftp_utils
import connector

def get_mock_files():
  return ['digital_spend.csv', 'tv_spend.csv']

class ConnectorTester(unittest.TestCase)
  @mock.patch('ftp_utils.get_files', side_effect=get_mock_files)
  def test_main_process(self, get_mock_files_function):
    # I want to use a mock version of the get_files function
    connector.main() 

当我调试我的测试时,我希望在 connector.py 的主函数中调用的 get_files 函数是 get_mock_files(),而不是 ftp_utils.get_files( ).我在这里做错了什么?我应该在我的代码中更改什么才能正确调用 get_mock_file() 模拟?

谢谢, 阿莱西奥

我觉得你的场景有几个问题:

  • connector.py 无法以这种方式从 ftp_utils.py 导入
  • 也不可以connector_tester.py
  • 作为一种习惯,你的测试文件最好以test_xxx.py
  • 的形式存在
  • 要使用 unittest 进行修补,请参阅 this example

一般来说,尽量提供最少的工作示例,以便每个人都可以更轻松地 运行 您的代码。

我对你的例子做了相当大的修改以使其工作,但基本上,问题是你修补 'ftp_utils.get_files' 而它不是在 connector.main() 内部实际调用的引用,而是可能 'connector.get_files'.

修改后的示例目录如下:

test_connector.py
ftp_utils.py
connector.py

test_connector.py:

import unittest
import sys
import mock
import connector

def get_mock_files(*args, **kwargs):
   return ['digital_spend.csv', 'tv_spend.csv']

class ConnectorTester(unittest.TestCase):
   def setUp(self):
      self.patcher = mock.patch('connector.get_files', side_effect=get_mock_files)
      self.patcher.start()

   def test_main_process(self):
      # I want to use a mock version of the get_files function
      connector.main()

suite = unittest.TestLoader().loadTestsFromTestCase(ConnectorTester)

if __name__ == "__main__":
   unittest.main()

NB: 运行ning connector.main()'connector.get_files'

时叫什么

connector.py:

from ftp_utils import *

def main():
   config = None
   downloaded_files = []
   downloaded_files = get_files(config)
   for f in downloaded_files:
      print(f)

connector/ftp_utils.py不变.