[TIP] Return value of a read-only attribute only settable via 'return_value' kwarg
Michael Foord
michael at voidspace.org.uk
Tue Apr 30 09:48:35 PDT 2013
On 30 Apr 2013, at 13:38, Balthazar Rouberol <rouberol.b at gmail.com> wrote:
> Hello all,
>
> I wanted to mock an class read only property (which only does some I/O with mongoDB) by setting its return_value in an entire unittest.TestCase scope.
>
> What I first tried was defining a patch in the classSetUp classmethod, then call its .start() method, and its .stop() method in tearDownClass.
>
> @classmethod
> def setUpClass(cls):
> # patch the Dataminer.blacklisted_domains so that it does not
> # communicate with the database
> cls.black_patch = mock.patch.object(
> Dataminer,
> 'blacklisted_domains',
> new_callable=mock.PropertyMock
> )
> cls.black_patch.return_value = ['some', 'manual', 'test', 'value']
Here cls.black_patch is the *patcher object* not the mock. It is responsible for creating the mock but is not itself the mock. So attaching a return_value to it has no effect. Calling patcher.start() creates and returns the mock object, so instead you should write:
mock_thing = cls.black_patch.start()
mock_thing.return_value = ['the', 'return', 'value']
All the best,
Michael
> cls.black_patch.start()
>
> @classmethod
> def tearDownClass(cls):
> cls.black_patch.stop()
>
>
> However, when I called the Dataminer.blacklisted_domains property later in a test, it returned <MagicMock name='blacklisted_domains()' id='34773392'>, and not the value I defined.
>
> What worked for me was passing the return_value as a kwarg to patch.object:
>
> @classmethod
> def setUpClass(cls):
> # patch the Dataminer.blacklisted_domains so that it does not
> # communicate with the database
> cls.black_patch = mock.patch.object(
> Dataminer,
> 'blacklisted_domains',
> new_callable=mock.PropertyMock,
> **{'return_value': ['some', 'manual', 'test', 'value']}
> )
> cls.black_patch.start()
>
> @classmethod
> def tearDownClass(cls):
> cls.black_patch.stop()
>
>
> With this method, the return value of the blacklisted_domains property of my Dataminer instance was what I defined in the classSetUp.
>
> Could anyone walk me through the differences between these two methods, as it's not really clear to me why the first would fail when the second would work..
>
> Thank you very much!
> --
> Balthazar Rouberol
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
--
http://www.voidspace.org.uk/
May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing
http://www.sqlite.org/different.html
More information about the testing-in-python
mailing list