19

I'm trying to find out why I don't seem to be able to use a mocked return value in a fixture. With the following imports

import pytest
import uuid

pytest-mock example that works:

def test_mockers(mocker):
    mock_uuid = mocker.patch.object(uuid, 'uuid4', autospec=True)
    mock_uuid.return_value = uuid.UUID(hex='5ecd5827b6ef4067b5ac3ceac07dde9f')
    # this would return a different value if this wasn't the case
    assert uuid.uuid4().hex == '5ecd5827b6ef4067b5ac3ceac07dde9f'

The above test passes. However as I will be using this in many test cases I thought I could just use a fixture:

@pytest.fixture
def mocked_uuid(mocker):
    mock_uuid = mocker.patch.object(uuid, 'uuid4', autospec=True)
    mock_uuid.return_value = uuid.UUID(hex='5ecd5827b6ef4067b5ac3ceac07dde9f')
    return mock_uuid

def test_mockers(mocked_uuid):
    # this would return a different value if this wasn't the case
    assert uuid.uuid4().hex == '5ecd5827b6ef4067b5ac3ceac07dde9f'

The above fails with the following output:

FAILED 
phidgetrest\tests\test_taskscheduler_scheduler.py:62 (test_mockers)
mocked_uuid = <function uuid4 at 0x0000029738C5B2F0>

    def test_mockers(mocked_uuid):
        # this would return a different value if this wasn't the case
>       assert uuid.uuid4().hex == '5ecd5827b6ef4067b5ac3ceac07dde9f'
E       AssertionError: assert <MagicMock name='uuid4().hex' id='2848515660208'> == '5ecd5827b6ef4067b5ac3ceac07dde9f'
E        +  where <MagicMock name='uuid4().hex' id='2848515660208'> = <MagicMock name='uuid4()' id='2848515746896'>.hex
E        +    where <MagicMock name='uuid4()' id='2848515746896'> = <function uuid4 at 0x0000029738C5B2F0>()
E        +      where <function uuid4 at 0x0000029738C5B2F0> = uuid.uuid4

tests\test_taskscheduler_scheduler.py:65: AssertionError

Hoping someone can help me understand why one works and the other doesn't or even better provide a solution that works!

I've also tried changing the scope of the fixture[session, module, function], just in case as I don't really understand why it's failing.

ehindy
  • 439
  • 1
  • 3
  • 10
  • Your example works fine for me, on both Python 2 and 3. – The Compiler Apr 12 '17 at 05:01
  • 1
    Could you please provide some specifics of your setup and what how you ran it? maybe I can track down what it is about my environment that isn't working. I am using python 3.6 (prob should have mentioned that) By all means I thought it should work and a github search showed similar examples of patch.object with pytest-mock in a fixture but not for me. – ehindy Apr 12 '17 at 08:44
  • I used the file you showed above, with an added `import pytest, uuid`. Then ran it with Python 3.6 and pytest 3.0.7. Looking at your stacktrace, you aren't actually running the snippet you showed above. – The Compiler Apr 12 '17 at 09:49
  • I'm wondering if it has somthign to do with my pytest.ini setup, i'm also running it with coverage and profiling...will spin up a new env and try a plain setup then add on to see where it might be going wrong. – ehindy Apr 12 '17 at 10:46

1 Answers1

19

So found the culprit and it was really silly, I actually retyped the examples above rather then copy and paste so my original code has an issue. In my fixture I had typed:

mock_uuid.return_value(uuid.UUID(hex='5ecd5827b6ef4067b5ac3ceac07dde9f'))

When it should have been:

mock_uuid.return_value = uuid.UUID(hex='5ecd5827b6ef4067b5ac3ceac07dde9f')

which I had in my example, hence it was working for others...so many hours lost...Feeling rather silly, however I hope this may help someone in the future...

ehindy
  • 439
  • 1
  • 3
  • 10