1

I am trying to mock a return value for a function that I am calling, with the help of pytest and monkeypatching.

I set up the fixture for my mock class, and I am trying to "overwrite" one of the methods in said class.

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)

However, I might be missing something, because calling assert_called_with throws an error:

________________________________________________________________ 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'

Is there something in my monkeypatching logic that I am misplacing?

3
  • 1
    What version of python and pytest are you using ? I tried to run your code and the only thing that fails is the for loop, but your error happened before that. The for loop error can be solved using MagicMock instead of Mock. Commented Nov 30, 2018 at 10:03
  • 1
    Oh actually, the code snippet and the error don't match: monkeypatch.setattr(FoggyCam, ... vs monkeypatch.setattr(mock_foggycam, ... Commented Nov 30, 2018 at 10:09
  • 1
    You are trying to make a mock that behaves like a mock (assert_called_with) and also keeps the original behavior of your get_mock_cookie (a function). You can try something like monkeypatch.setattr(mock_foggycam, "get_unpickled_cookies", Mock(wraps=get_mock_cookie)) . Commented Nov 30, 2018 at 10:20

1 Answer 1

2

Follow up from my comments. You are basically trying to make a mock that behaves like a mock (so that assert_called_with is available) and also executes your get_mock_cookie (a function).

This is what the wraps argument does. Documented here: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

You can try something like this:

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

The error that you are getting is basically telling you that you were trying to call assert_called_with on a function object (your get_mock_cookie).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! That gets the code to go past the original hurdle, however that also makes the object non-iterable, so the test fails at the for loop. Is there a way to make the mock method return an iterable collection?
Your get_mock_cookie function returns a list, so that should be iterable. In general you can use MagicMock instead of Mock if you want your mocks to be iterable. docs.python.org/3/library/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.