在 Python 中模拟嵌套方法

凯尔

在这方面绞尽脑汁。我想模拟生成器方法self.api.redditor(username).comments.new(limit=num)self.api.redditor(username).submissions.new(limit=num)以下,其中self.api分配给一个类实例,如self.api = PrawReddit()

我正在尝试测试结果的大小: self.assertEqual(len(result), 5)

到目前为止,我尝试过MockPraw.return_value.redditor.return_value.comments.return_value.new.return_value.__iter__.return_value = iter(['c' * 10])但测试失败AssertionError: 0 != 5

任何提示非常感谢。

def get_comments_submissions(self, username, num=5):
    """Return max `num` of comments and submissions by `username`."""
    coms = [
        dict(
            title=comment.link_title,
            text=comment.body_html,
            subreddit=comment.subreddit_name_prefixed,
            url=comment.link_url,
            created=datetime.fromtimestamp(comment.created_utc, pytz.utc),
        )
        for comment in self.api.redditor(username).comments.new(limit=num)
    ]
    subs = [
        dict(
            title=submission.title,
            text=submission.selftext_html,
            subreddit=submission.subreddit_name_prefixed,
            url=submission.url,
            created=datetime.fromtimestamp(submission.created_utc, pytz.utc),
        )
        for submission in self.api.redditor(username).submissions.new(limit=num)
    ]
    return coms + subs if len(coms + subs) < num else (coms + subs)[:num]
蒂姆

要模拟生成器(除非您使用特定的生成器功能),您可以使用迭代器作为替代,例如

import unittest.mock as mock

generator_mock = Mock(return_value=iter(("foo", "bar")))

当您在示例中使用嵌套结构时,这会变得稍微复杂一些,属性访问会自动处理,但return_value必须定义函数。从你的例子:

# API mock
mock_api = Mock()
mock_api.redditor.return_value = mock_subs = Mock()

# Submissions mock
mock_subs.new.return_value = iter(("foo", "bar"))

然后可以调用和断言

for item in mock_api.api.redditor("user").submissions.new(limit=5):
    print(item)

mock_api.redditor.assert_called_with("user")
mock_subs.new.assert_called_with(limit=5)

由于 API 是同一类的成员,因此必须对其进行猴子修补,例如:

target = Praw()
target.api = mock_api()
target.get_comments_submissions("user")

mock_api.redditor.assert_called_with("user")
mock_subs.new.assert_called_with(limit=5)

请注意,iterator返回值是单个实例,第二次调用获取迭代器将返回相同的实例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章