【问题标题】:pytest & monkeypatching - cannot get return valuepytest & monkeypatching - 无法获得返回值
【发布时间】:2019-05-02 09:41:33
【问题描述】:

我正在尝试在 pytest 和 monkeypatching 的帮助下模拟我正在调用的函数的返回值。

我为我的模拟类设置了夹具,并且我试图“覆盖”所述类中的一种方法。

from foggycam import FoggyCam
from datetime import datetime

@pytest.fixture
def mock_foggycam():
    return Mock(spec=FoggyCam)

def test_start(mock_foggycam, monkeypatch):
    def get_mock_cookie():
        temp = []
        temp.append(Cookie(None, 'token', '000000000', None, None, 'somehost.com', 
            None, None, '/', None, False, False, 'TestCookie', None, None, None))
        return temp

    monkeypatch.setattr(FoggyCam, 'get_unpickled_cookies', get_mock_cookie)

    cookies = mock_foggycam.get_unpickled_cookies()
    mock_foggycam.get_unpickled_cookies.assert_called_with()

    for pickled_cookie in cookies:
        mock_foggycam.cookie_jar.set_cookie(pickled_cookie)

但是,我可能会遗漏一些东西,因为调用 assert_called_with 会引发错误:

________________________________________________________________ test_start ________________________________________________________________

mock_foggycam = <Mock spec='FoggyCam' id='4408272488'>, monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x106c0e5c0>

    def test_start(mock_foggycam, monkeypatch):
        def get_mock_cookie():
            temp = []
            temp.append(Cookie(None, 'token', '000000000', None, None, 'somehost.com',
                None, None, '/', None, False, False, 'TestCookie', None, None, None))
            return temp

        monkeypatch.setattr(mock_foggycam, 'get_unpickled_cookies', get_mock_cookie)

        cookies = mock_foggycam.get_unpickled_cookies()
>       mock_foggycam.get_unpickled_cookies.assert_called_with()
E       AttributeError: 'function' object has no attribute 'assert_called_with'

我的猴子补丁逻辑中有什么地方放错了吗?

【问题讨论】:

  • 你用的是什么版本的python和pytest?我试图运行你的代码,唯一失败的是 for 循环,但你的错误发生在此之前。使用 MagicMock 代替 Mock 可以解决 for 循环错误。
  • 哦实际上,代码 sn-p 和错误不匹配:monkeypatch.setattr(FoggyCam, ... vs monkeypatch.setattr(mock_foggycam, ...
  • 您正在尝试制作一个行为类似于模拟 (assert_called_with) 的模拟,并且还保持您的 get_mock_cookie(一个函数)的原始行为。你可以试试monkeypatch.setattr(mock_foggycam, "get_unpickled_cookies", Mock(wraps=get_mock_cookie))

标签: python unit-testing mocking tdd pytest


【解决方案1】:

从我的 cmets 跟进。您基本上是在尝试制作一个行为类似于模拟的模拟(以便assert_called_with 可用)并执行您的get_mock_cookie(一个函数)。

这就是wraps 参数的作用。记录在这里:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

你可以试试这样的:

monkeypatch.setattr(mock_foggycam, "get_unpickled_cookies", Mock(wraps=get_mock_cookie)) 

你得到的错误基本上是告诉你你试图在一个函数对象(你的get_mock_cookie)上调用assert_called_with

【讨论】:

  • 谢谢!这使代码越过了最初的障碍,但这也使对象不可迭代,因此测试在 for 循环中失败。有没有办法让 mock 方法返回一个可迭代的集合?
  • 你的 get_mock_cookie 函数返回一个列表,所以它应该是可迭代的。一般来说,如果你希望你的模拟是可迭代的,你可以使用MagicMock 而不是Mockdocs.python.org/3/library/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2020-10-28
相关资源
最近更新 更多