python-3.x - 在databricks中,在不同笔记本中的函数上使用unittest.mock.patch

标签 python-3.x unit-testing databricks

在 databricks 上,我有一个代码笔记本和一个单元测试笔记本。

使用“%run”命令将代码“导入”到单元测试笔记本中。

如何从单元测试笔记本中创建代码笔记本中函数之一的模拟对象?我通常会使用补丁上下文管理器来实现此目的。

这是包含要修补的函数 (get_name) 的代码笔记本:

# Databricks notebook source
def get_name_func():
  return 'name1'

这是单元测试代码:

# Databricks notebook source:

from unittest.mock import patch
import inspect


# COMMAND ----------


# MAGIC %run ./get_name


# COMMAND ----------


def local_get_name():
  return 'name_local'


# COMMAND ----------


get_name_func()


# COMMAND ----------


print(inspect.getmodule(get_name_func))
print(inspect.getsourcefile(get_name_func))


# COMMAND ----------


inspect.unwrap(get_name_func)


# COMMAND ----------


with patch('get_name_func') as mock_func:
  print(mock_func)


# COMMAND ----------
with patch('local_get_name') as mock_func:
  print(mock_func)

对于本地函数和代码笔记本中的函数,两次修补尝试都会给出相同的错误:

TypeError: Need a valid target to patch. You supplied: 'get_name_func'

检查命令返回:

<module '__main__' from '/local_disk0/tmp/1625490167313-0/PythonShell.py'>
<command-6807918>

Out[38]: <function __main__.get_name_func()>

我尝试了模块路径的各种组合,但没有成功。

奇怪的是,__name__ 返回'__main__'。但是在补丁调用中使用路径 '__main__.get_name_func' 不起作用。

我的信念是,如果该对象存在于笔记本中(确实如此),那么它一定是可修补的。

有什么建议吗?

最佳答案

我必须制作自己的修补功能:

class FunctionPatch():
  '''
  This class is a context manager that allows patching of functions "imported" from another notebook using %run.
  
  The patch function must be at global scope (i.e. top level)
  '''
  def __init__(self, real_func_name: str, patch_func: Callable):
    self._real_func_name = real_func_name
    self._patch_func = patch_func
    self._backup_real_func = None
    
  def __enter__(self):
    self._backup_real_func = globals()[self._real_func_name]
    globals()[self._real_func_name] = self._patch_func
    
  def __exit__(self, exc_type, exc_value, tb):
    if exc_type is not None:
      traceback.print_exception(exc_type, exc_value, tb)
      
    globals()[self._real_func_name] = self._backup_real_func

用法:

def test_function_patch_real_func():
  return 'real1'

def test_function_patch():
  
  assert test_function_patch_real_func() == 'real1'
  
  def mock_func():
    return 'mock1'
  
  with FunctionPatch('test_function_patch_real_func', mock_func):
    assert test_function_patch_real_func() == 'mock1' 
    
  assert test_function_patch_real_func() == 'real1'

关于python-3.x - 在databricks中,在不同笔记本中的函数上使用unittest.mock.patch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68259129/

相关文章:

python - 如何使用opencv训练级联

php - 使用 PHPUnit 测试具有多个参数的构造函数

wcf - 您如何配置 WCF 以支持使用 net.pipe 的主机和客户端在同一进程中的 FaultContract?

apache-spark - 无法在 databricks 上运行 johnsnow OCR 笔记本

apache-spark - 区分大小写加入 Spark

python - pip 安装在共享目录 (windows)

python - opencv FisherFaceRecognizer 的 train() 函数显示 TypeError : src is not a numpy array, 既不是标量

python - 在 Mac OS X 上安装了 Python 3,但它仍然是 Python 2.7

unit-testing - Karma - 使用 PhantomJS 而不是 Chrome

azure - 在databricks中创建数据框时获取 "error while emitting; method too large"