属性的魔术模拟设置值仅获取第一个值



我正在使用pytest3.7进行测试。我想模拟res,这是get_res_function的返回值。res.property1[key1][keyN].property2是我想嘲笑的价值。这是我的测试:

@mock.patch("mypkg.get_res_function")
def test_function(mock_res):
returner = mock.MagicMock()
returner.property1["key1"]["key2"].property2 = "11111"
returner.property1["key1"]["key3"].property2 = "22222"
mock_res.return_value = returner

但是,我想模拟的两个值都只使用第一行模拟的值,这意味着mock_res.property1["key1"]["key2"].property2 = "11111", mock_res_property1["key1"]["key3"].property2 = "11111"如果在测试代码中反转它,这意味着在"11111"之前放置"22222",

returner.property1["key1"]["key2"].property2 = "22222"
returner.property1["key1"]["key3"].property2 = "11111"

那么所有的结果都是"22222",怎么了?

这很棘手,因为项目访问语法thing[index]实际上是在调用魔术方法__getitem__,这就是您想要模拟的。

所以这个

returner.property1["key1"]["key2"].property2 = "11111"

就像这样做一样

returner.property1.__getitem__.return_value.__getitem__.return_value.property2 = "11111"

这没关系,因为它更简洁一些,但是键实际上被忽略了。

您可以使用带有side_effectPropertyMock按顺序返回不同的内容:

type(returner.property1.__getitem__.return_value.__getitem__.return_value).property2 = PropertyMock(side_effect=["11111", "22222"])

或者,返回以获取项目语法:

type(returner.property1["this is"]["ignored"]).property2 = PropertyMock(side_effect=["11111", "22222"])

它应该有效:

returner.property1["foo"]["bar"].property2
> '11111'
returner.property1["foo"]["bar"].property2
> '22222'

但是,请记住,无论输入键如何,它都将返回相同的值。如果用完side_effects,它会提高StopIteration.

您可以断言哪些键实际用于调用__getitem__

returner.property1.__getitem__.call_args_list
returner.property1.__getitem__.return_value.__getitem__.call_args_list

如果您愿意,可以将函数作为side_effect传递,而是使用与模拟(键(相同的参数调用它,然后您可以根据键决定返回什么。但这需要在__getitem__模拟中完成,而不是在财产模拟中完成。

一些参考资料:

  • __getitem__: https://docs.python.org/3/reference/datamodel.html#object。获取项
  • PropertyMock: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock
  • side_effect: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect

相关内容

  • 没有找到相关文章

最新更新