如何将方法修补到 Mock() 中?
How to patch a method into a Mock()?
我有一个功能要测试。 datahandler
参数是我在模块其他地方定义的 class Datahandler
的一个实例。
def create_row(row_content, datahandler):
row = {}
# Here comes some code that fills the "row" dictionary based on what was passed in row_content
row = datahandler.process_row(row)
# some more handling happens to the processed row
return row
我尝试编写单元测试,但我遇到了困难,因为我似乎无法找到一种方法来替换模拟数据处理程序的 process_row
方法:
class TestCreateRow(unittest.TestCase):
def fake_process_row(row):
return row
def test_create_row(self):
# create a suitable row_content here
# row_content = ...
expected = {"first column":"first value", "second column":"second value"}
datahandler = Mock()
# !!! This doesn't work - what is the correct solution?
datahandler.process_row = self.fake_process_row
result = create_row(row_content, datahandler)
self.assertDictEqual(expected, result)
我尝试使用 return_value
和 side_effects
将 fake_process_row
函数分配给模拟数据处理程序,甚至将 fake_process_row
修补为 Mock
但是对于我尝试过的任何合成正确的版本,调用 datahandler.process_row(row)
继续 return a Mock(),当我需要它实际调用我的 fake_process_row
函数时,它可以 return a实排.
我见过一些解决方案,在测试中,创建了一个真实的 datahandler
对象,并将 fake_process_row
修补到其中。我不想这样做,因为真正的 class 实例化并不是完全微不足道的。只使用一种“工作”方法进行模拟会容易得多,就像我可以使用 属性.
的“工作”return 值进行模拟一样
所以我找到了解决方案,那就是创建两个单独的模拟。
def test_create_row(self):
# create a suitable row_content here
# row_content = ...
expected = {"first column":"first value", "second column":"second value"}
datahandler = Mock()
# The magic happens here
method_mock = Mock(side_effect = self.fake_process_row)
datahandler.process_row = method_mock
result = create_row(row_content, datahandler)
self.assertDictEqual(expected, result)
使用 side_effect
有点违反直觉,但一旦访问 Mock()
就会发生这种情况。所以当我们将datahandler.process_row
设置为具有这种副作用的Mock时,它会在被测代码调用process_row
方法时触发,它也足够聪明,可以正确传递参数。
我有一个功能要测试。 datahandler
参数是我在模块其他地方定义的 class Datahandler
的一个实例。
def create_row(row_content, datahandler):
row = {}
# Here comes some code that fills the "row" dictionary based on what was passed in row_content
row = datahandler.process_row(row)
# some more handling happens to the processed row
return row
我尝试编写单元测试,但我遇到了困难,因为我似乎无法找到一种方法来替换模拟数据处理程序的 process_row
方法:
class TestCreateRow(unittest.TestCase):
def fake_process_row(row):
return row
def test_create_row(self):
# create a suitable row_content here
# row_content = ...
expected = {"first column":"first value", "second column":"second value"}
datahandler = Mock()
# !!! This doesn't work - what is the correct solution?
datahandler.process_row = self.fake_process_row
result = create_row(row_content, datahandler)
self.assertDictEqual(expected, result)
我尝试使用 return_value
和 side_effects
将 fake_process_row
函数分配给模拟数据处理程序,甚至将 fake_process_row
修补为 Mock
但是对于我尝试过的任何合成正确的版本,调用 datahandler.process_row(row)
继续 return a Mock(),当我需要它实际调用我的 fake_process_row
函数时,它可以 return a实排.
我见过一些解决方案,在测试中,创建了一个真实的 datahandler
对象,并将 fake_process_row
修补到其中。我不想这样做,因为真正的 class 实例化并不是完全微不足道的。只使用一种“工作”方法进行模拟会容易得多,就像我可以使用 属性.
所以我找到了解决方案,那就是创建两个单独的模拟。
def test_create_row(self):
# create a suitable row_content here
# row_content = ...
expected = {"first column":"first value", "second column":"second value"}
datahandler = Mock()
# The magic happens here
method_mock = Mock(side_effect = self.fake_process_row)
datahandler.process_row = method_mock
result = create_row(row_content, datahandler)
self.assertDictEqual(expected, result)
使用 side_effect
有点违反直觉,但一旦访问 Mock()
就会发生这种情况。所以当我们将datahandler.process_row
设置为具有这种副作用的Mock时,它会在被测代码调用process_row
方法时触发,它也足够聪明,可以正确传递参数。