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"
在理解如何模拟 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"