首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python中的模拟嵌套方法

Python中的模拟嵌套方法
EN

Stack Overflow用户
提问于 2019-08-06 08:53:59
回答 2查看 1.7K关注 0票数 0

为这事绞尽脑汁。我想模拟下面的生成器方法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测试失败

任何建议都非常感谢。

代码语言:javascript
运行
复制
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]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-06 09:24:46

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

代码语言:javascript
运行
复制
import unittest.mock as mock

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

当你有嵌套结构时,比如你的例子,这会变得有点复杂,属性访问是自动处理的,但是必须定义来自函数的return_value。从您的示例中可以看出:

代码语言:javascript
运行
复制
# API mock
mock_api = Mock()
mock_api.redditor.return_value = mock_subs = Mock()

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

然后可以调用并断言这一点

代码语言:javascript
运行
复制
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是同一类的成员,因此必须对其进行猴子修补,例如:

代码语言:javascript
运行
复制
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是一个实例,第二次调用get迭代器将返回相同的实例。

票数 1
EN

Stack Overflow用户

发布于 2019-08-06 09:32:47

像使用pytest-mock一样编写,所有事情都在mymodule中发生(您在模块顶部导入了类,如from xy import PrawReddit):

代码语言:javascript
运行
复制
mocker.patch("datetime.fromtimestamp")
mocked_comment = mocker.MagicMock()
mocked_submission = mocker.MagicMock()
mocked = mocker.patch("mymodule.PrawReddit")
mocked.return_value.redditor.return_value.comments.new.return_value = [mocker.MagicMock(), mocked_comment]
mocked.return_value.redditor.return_value.submisions.new.return_value = [mocker.MagicMock(), mocked_submission]

returned = instance.get_comments_submissions("foo", num=2)
assert mocked.return_value.redditor.call_count = 2
mocked.return_value.assert_called_with("foo")
assert returned[-1]["link_title"] == mocked_comment.link_title

另一个带有相同简介的测试调用:

代码语言:javascript
运行
复制
# ...
returned = instance.get_comments_submissions("foo")
assert mocked.return_value.redditor.call_count = 2
mocked.return_value.assert_called_with("foo")
assert returned[1]["link_title"] == mocked_comment.link_title
assert returned[-1]["title"] == mocked_submission.title
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57367624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档