2017-06-23 60 views
0

假设有一个功能download_page_html(url),它下载由(有效)url指向的页面的HTML内容。各种功能使用它download_page_html做他们的工作。如何拦截函数调用并用pytest更改参数?

现在,测试时我不想从维基百科下载HTML,而是从本地主机下载。

那么如何拦截各种函数调用download_page_html并替换url参数的值呢?

回答

-1

使用Python的stdlib unittest.mock.patch - 它既可以作为装饰器使用,也可以作为上下文管理器使用(即使用with语句)。

如果您在new关键字参数传递,功能pacthed到 - 你只要把一个班轮调用与 参数原有的功能选择:

from unittest.mock import patch 

from mymodule import download_page_html as original_download_page 

@patch('mymodule.download_page_html', new=lambda page: original_download_page("http://localhost/page.html")) 
def test_my_test_function(...): 
    ... 
+0

无需通过混合'pytest'和'unittest'使事情变得复杂。如果您已经在使用'pytest',只需使用其内置的monkeypatch工具即可。 – Anthon

+0

它并不复杂 - unittest.mock被推荐并用于pytest文档。这只是愚蠢的“报复”。尽量客观。 – jsbueno

+0

假设用“pytest文档”表示pytest文档(如果不是其他内容?),我强烈建议您打开[pytest文档页面](https://docs.pytest.org/en/latest/contents.html)并搜索'unittest.mock'或'from unittest'或者下载[PDFdocumentation](https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf)并搜索。我找到了使用'unittest.mock'的零结果。所以,请支持您的索赔与一些参考或解释你认为是什么“pytest文件” – Anthon

-1

您应该添加一个可选dph=None参数传送给“各种功能”,然后在函数体重新分配,如果有必要的硬编码download_page_html功能:

def my_various_function(url, arg2, kw1=val1, dph=None): 
    if dph is None: 
     dph = download_page_html 
    res = dph(url) 

如果你不认为你的设计令苏CH的改变,使用内置monkeypatchpytest的:

import pytest # no need to import monkeypatch from pytest 

def test_mytest(monkeypatch): 
    url = 'some_url' 
    def mockdlpage(url): 
     return 'the_mock_data' 
    monkeypatch.setattr(yourmodule, 'download_page_html', mockdlpage) 
    data = download_page_html(url) 
+1

除非改变功能是系统的必要功能,否则这是一个非常糟糕的做法。你不应该为了能够测试它而使代码复杂化。 – jsbueno

+0

使用硬编码顶级功能的灵活性在我的经验中是您设计的必要基础。 – Anthon