tisq
tisq

Reputation: 85

Is it possible to patch a method that is invoked in another class?

I don't know how to mock/patch a method inside a class within a unittest. I think about following workaround:

class A():
    def _get_datetime(self, days):
        return (datetime.now() + timedelta(days=days)).strftime('%Y-%m-%d')

    def do_something(self):
        date = self._get_datetime()

Now I have my TestClass in my unittest as follows:

class TestClass():
    def test_one:
        # do some things here
        next_day = (datetime.now()).date()+relativedelta(days=+1)
        self._test_a(self._mocked_get_datetime(next_day))

    @patch('path.to.my.class.A', '_get_datetime')
    def _test_a(self, mock_method):
        self.env['A'].do_something()

    def _mocked_get_datetime(self, date):
        return date

How can I mock the _get_datetime() method in class A?

I would like to define the date that is used in do_something() method in class A in my testing environment. Is that possible?

Thanks!!

Upvotes: 1

Views: 607

Answers (1)

Lin Du
Lin Du

Reputation: 102327

Here is the unit test solution using patch.object to mock _get_datetime method of class A

a.py:

import datetime
from datetime import timedelta


class A():
    def _get_datetime(self, days):
        return (datetime.now() + timedelta(days=days)).strftime('%Y-%m-%d')

    def do_something(self):
        date = self._get_datetime()
        return date

test_a.py:

import unittest
from unittest.mock import patch
from datetime import datetime
from a import A

next_day = datetime.now().date()


class TestClass(unittest.TestCase):
    @patch.object(A, '_get_datetime', return_value=next_day)
    def test_do_something(self, mock_get_datetime):
        a_instance = A()
        actual = a_instance.do_something()
        self.assertEqual(actual, next_day)
        mock_get_datetime.assert_called_once()


if __name__ == '__main__':
    unittest.main()

Unit test result with coverage report:

(venv) ☁  python-codelab [master] ⚡  coverage run /Users/ldu020/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/58857424/test_a.py    
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
(venv) ☁  python-codelab [master] ⚡  coverage report -m                                                                                         
Name                                   Stmts   Miss  Cover   Missing
--------------------------------------------------------------------
src/stackoverflow/58857424/a.py            8      1    88%   7
src/stackoverflow/58857424/test_a.py      13      0   100%
--------------------------------------------------------------------
TOTAL                                     21      1    95%

Source code: https://github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/58857424

Upvotes: 1

Related Questions