Monkeypatching __init__ 上未设置的实例属性

Monkeypatching an instance attribute not set on __init__

在理解如何模拟 class 实例属性时遇到一些问题。 class 由包“newspaper3k”定义,例如:from newspaper import Article.

我在这上面纠结了一段时间,看了文档好像也无济于事。任何人都可以给我一个指导吗?

"""utils/summarizer.py module """

import nltk
from newspaper import Article


def generate_summary(url: str) -> str:
    article = Article(url)
    article.download()
    article.parse()

    try:
        nltk.data.find("tokenizers/punkt")
    except LookupError:
        nltk.download("punkt")
    finally:
        article.nlp()

    return article.summary

我目前的尝试看起来像这样...恐怕我混淆了库和在 python 中使用 pytest 进行模拟的方式。

from newspaper import Article

import app.utils.summarizer as summarizer


def test_generate_summary(mocker, monkeypatch):
    article = mocker.MagicMock(Article)
    type(article).summary = mocker.PropertyMock(return_value="abc")

    # methods = {
    #     'download.return_value': None,
    #     'parse.return_value': None,
    #     'nlp.return_value': None,
    # }
    # article_mock = mocker.MagicMock(summary="abc", **methods)
    # monkeypatch.setattr("newspaper.article.Article", article_mock)

    monkeypatch.setattr(Article, "download", lambda _: None)
    monkeypatch.setattr(Article, "parse", lambda _: None)
    monkeypatch.setattr(Article, "nlp", lambda _: None)

    monkeypatch.setattr(
        "nltk.data.find", lambda _: "https://test-url.com/resource?name=foo#bar"
    )

    summary = summarizer.generate_summary("https://test-url.com")

    assert summary == "abc"

有什么建议吗?另外,无论如何我可以更轻松地模拟“下载”、“解析”和“nlp”方法吗?

遵循 MrBean Bremen 建议...再次阅读文档后,我再次学到了很多重要的东西。我还学习了一些教程,但最终,none 解决了我的问题,或者至少没有,IMO,善于解释我到底在做什么。

I was able to mock class attributes and instance methods when all I wanted to was to mock an instance attribute. I also read many tutorials, which did not help me fully understand what I was doing either.

最终,在绝望地 google 搜索一段我自己的代码后,应该不会产生任何重要的结果(即:mocker.patch.object(Article, summary="abc", create=True)),我找到了我在周围找到的最好的教程上周的网络,终于帮助我连接了文档。

我的问题的最终解决方案是(文档字符串包括帮助我的教程):

def test_generate_summary(mocker):
    """See comprehensive guide to pytest using pytest-mock lib:

        https://levelup.gitconnected.com/a-comprehensive-guide-to-pytest-3676f05df5a0
    """
    mock_article = mocker.patch("app.utils.summarizer.Article")
    mock_article().summary = "abc"

    mocker.patch("app.utils.summarizer.nltk.data.find", return_value=None)

    summary = summarizer.generate_summary("https://test-url.com")

    assert summary == "abc"