getattr() 调用的 Python 模拟返回 [英] Python mock return of a getattr() call

查看:47
本文介绍了getattr() 调用的 Python 模拟返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能会在这里落入 XY 问题陷阱.这是我真正想要知道的内容.>

我有以下功能:

def foo():bar = funcToGetBar()return bar.getattr("some_attr", None)

在我的测试中,我尝试这样做:

mocked_bar = MagicMock()expected_return_val = [obj1, obj2, ...]funcToGetBar.return_value = mocked_bar # funcToGetBar 被修补def testGetBar(self):assertEqual(expected_return_val, foo())

现在我想做的是将 expected_return_val 提供到 bar 对象的 some_attr 属性上.

我尝试过使用 PropertyMock:

type(mocked_bar).getattr = PropertyMock(return_value=expected_return_value)

运行我的测试时出现错误:

TypeError: 'list' 对象不可调用

如果 return_value 设置为标量(不是列表),则实际函数中 getattr 调用的结果是一个模拟,而不是标量我提供.

另外,我担心模拟 getattr 方法,因为它是一个通用方法,可能会在我的函数中的其他地方使用.如何在被测模拟对象的属性上设置列表?

解决方案

根据文档,Mock 的 return_value 不可迭代.要获得可迭代的 return_value,请使用 side_effect.

mocked_bar = MagicMock()mocked_bar.side_effect = [obj1, obj2, ...]

文档位于 https:///docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

特别是:

side_effect:每当调用 Mock 时都会调用的函数.请参阅 side_effect 属性.用于引发异常或动态更改返回值.该函数使用与模拟相同的参数调用,除非它返回 DEFAULT,否则将使用该函数的返回值作为返回值.

Edit: I might be falling the XY problem trap here. Here's what I really want to know.

I have the following function:

def foo():
  bar = funcToGetBar()
  return bar.getattr("some_attr", None)

In my test, I try to do:

mocked_bar = MagicMock()
expected_return_val = [obj1, obj2, ...]
funcToGetBar.return_value = mocked_bar  # funcToGetBar is patched

def testGetBar(self):
  assertEqual(expected_return_val, foo())

Now what I want to do is to provide the expected_return_val onto the some_attr attribute on the bar object.

I have tried using PropertyMock:

type(mocked_bar).getattr = PropertyMock(return_value=expected_return_value)

Running my test I get the error:

TypeError: 'list' object is not callable

If the return_value is set to a scalar (not a list), the result of the getattr call in the real function is a mock, and not the scalar I provided.

Also, I'm worried about mocking out the getattr method, since it is a common method that will probably be used elsewhere in my function. How can I set a list on an attribute of my mock object under test?

解决方案

Per the documentation, Mock's return_value isn't iterable. To get an iterable return_value, use side_effect.

mocked_bar = MagicMock()
mocked_bar.side_effect = [obj1, obj2, ...]

edit: Documentation is located at https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

specifically:

side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value.

这篇关于getattr() 调用的 Python 模拟返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆