Snuh
Snuh

Reputation: 360

pytest - using patch as a decorator to patch a constant

I have an object MyObject which uses a constant defined in mymodule.constants.MYCONSTANT. I can successfully patch the constant using a context manger like so:

import pytest
from unittest.mock import patch

def test_constant(self):
    with patch('mymodule.constants.MYCONSTANT', 3):
        MyObject()

However, I can't figure out how to use the equivalent patching using patch as a decorator:

@patch('mymodule.constants.MYCONSTANT', 3)
def test_constant(self, mock_constant):
     MyObject()

The above fails with a fixture mock_constant not found error. I tried using

@patch('mymodule.constants.MYCONSTANT', return_value=3)

But MYCONSTANT doesn't get replaced with the value of 3.

Upvotes: 2

Views: 3916

Answers (2)

ToastedGuy2
ToastedGuy2

Reputation: 173

Guys the order of parameters matter so first mocks then fixtures, otherwise it will still throw you the same error.

@patch('server.app.UserValidator')
def test_first_mocks(self,mock_user_validator:MagicMock,client_fixture:FlaskClient):
    # Arrange
    input = {'password':'internal','username':'error'}
    mock_user_validator.side_effect = ValueError('testing')
    # Act
    response = client_fixture.post('/api/users',json=input)
    # Assert
    mock_user_validator.assert_called_once()
    assert response.status_code == 500

Upvotes: 2

Niel Godfrey P. Ponciano
Niel Godfrey P. Ponciano

Reputation: 10709

This is aligned to the behavior as documented:

unittest.mock.patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

... If patch() is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function.

So, if you want to pass the extra argument to the decorated function, don't set the new argument:

@patch('mymodule.constants.MYCONSTANT')
def test_constant(self, mock_constant):
    ...

Setting the new argument means no extra argument would be passed:

@patch('mymodule.constants.MYCONSTANT', 3)
def test_constant(self):
    ...

Upvotes: 2

Related Questions