如何在 Python 3.5 中使用 unittest.mock 模拟导入的库方法?
How to mock imported library methods with unittest.mock in Python 3.5?
是否可以在 Python 3.5 中使用 unittest.mock 模拟导入模块的方法?
# file my_function.py
import os
my_function():
# do something with os, e.g call os.listdir
return os.listdir(os.getcwd())
# file test_my_function.py
test_my_function():
os = MagickMock()
os.listdir = MagickMock(side_effect=["a", "b"])
self.assertEqual("a", my_function())
我预计 os.listdir 方法 returns 在第一次调用时指定 side_effect "a",但在 my_function 内部未修补 os.listdir 被调用。
unittest.mock
有两个主要职责:
- 定义
Mock
对象:旨在跟随您的剧本并记录对模拟对象的每次访问的对象
- 修补引用并恢复原始状态
在您的示例中,您需要两种功能:修补生产代码中使用的 os.listdir
引用,您可以完全控制模拟的响应方式。 patch
, some details to take care on how use it and cavelets to know.
有很多种使用方法
在您的情况下,您需要测试 my_function()
行为并且需要修补 os.listdir()
和 os.getcwd()
。此外,您需要的是控制 return_value
(查看 return_value
和 side_effect
差异的指向文档)。
我稍微重写了您的示例以使其更加完整和清晰:
my_function(nr=0):
l = os.listdir(os.getcwd())
l.sort()
return l[nr]
@patch("os.getcwd")
@patch("os.listdir", return_value=["a","b"])
def test_my_function(mock_ld, mock_g):
self.assertEqual("a", my_function(0))
mock_ld.assert_called_with(mock_g.return_value)
self.assertEqual("a", my_function())
self.assertEqual("b", my_function(1))
with self.assertRaises(IndexError):
my_function(3)
我使用了装饰器语法,因为我认为它是一种更简洁的方式;此外,为了避免引入太多细节,我没有使用 autospecing
我认为这是一个非常好的做法。
最后说明:mocking 是一个强大的工具,但要使用它而不是滥用它,补丁只是你需要的补丁,仅此而已。
是否可以在 Python 3.5 中使用 unittest.mock 模拟导入模块的方法?
# file my_function.py
import os
my_function():
# do something with os, e.g call os.listdir
return os.listdir(os.getcwd())
# file test_my_function.py
test_my_function():
os = MagickMock()
os.listdir = MagickMock(side_effect=["a", "b"])
self.assertEqual("a", my_function())
我预计 os.listdir 方法 returns 在第一次调用时指定 side_effect "a",但在 my_function 内部未修补 os.listdir 被调用。
unittest.mock
有两个主要职责:
- 定义
Mock
对象:旨在跟随您的剧本并记录对模拟对象的每次访问的对象 - 修补引用并恢复原始状态
在您的示例中,您需要两种功能:修补生产代码中使用的 os.listdir
引用,您可以完全控制模拟的响应方式。 patch
, some details to take care on how use it and cavelets to know.
在您的情况下,您需要测试 my_function()
行为并且需要修补 os.listdir()
和 os.getcwd()
。此外,您需要的是控制 return_value
(查看 return_value
和 side_effect
差异的指向文档)。
我稍微重写了您的示例以使其更加完整和清晰:
my_function(nr=0):
l = os.listdir(os.getcwd())
l.sort()
return l[nr]
@patch("os.getcwd")
@patch("os.listdir", return_value=["a","b"])
def test_my_function(mock_ld, mock_g):
self.assertEqual("a", my_function(0))
mock_ld.assert_called_with(mock_g.return_value)
self.assertEqual("a", my_function())
self.assertEqual("b", my_function(1))
with self.assertRaises(IndexError):
my_function(3)
我使用了装饰器语法,因为我认为它是一种更简洁的方式;此外,为了避免引入太多细节,我没有使用 autospecing 我认为这是一个非常好的做法。
最后说明:mocking 是一个强大的工具,但要使用它而不是滥用它,补丁只是你需要的补丁,仅此而已。