derwiki-adroll / mock

Automatically exported from code.google.com/p/mock
BSD 2-Clause "Simplified" License
0 stars 0 forks source link

Patching a class will result in instantiating the same mock instance (creates singleton) #101

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
When patching a class or a class method I would expect that each new instance 
will be a different mock object. 

I have the following code, that when patching a class will transform the class 
into a singleton.

Is this a bug or a feature.

Is there a method for pathcing a class so that it will produces different 
instances?

Many thanks!

-------
Here is the code.

from unittest2 import TestCase
from mock import mock

class DemoClass(object):
    def __init__(self):
        pass

class MyTest(TestCase)
    def test_patch_instance(self):
        with patch('module.DemoClass'):
            one = DemoClass()
            two = DemoClass()
            self.assertIsNot(one, two)

Original issue reported on code.google.com by adiroi...@gmail.com on 28 Jun 2011 at 2:36

GoogleCodeExporter commented 9 years ago
No, sorry. The return value is a single object. If you want multiple returned 
mocks you will have to implement a side_effect that does this for you.

(Otherwise getting access back to the returned mocks to make assertions on them 
would be difficult.)

Original comment by fuzzyman on 28 Jun 2011 at 2:38

GoogleCodeExporter commented 9 years ago
Thank you very much for you comment.

Using a side effect solves the usage of patch but I can not use the same 
technique for patch.object.

I think that it is worth mentioning in TODO and limitation section and add the 
patch on classes in Other examples section.

Cheers,
Adi 

Original comment by adiroi...@gmail.com on 28 Jun 2011 at 3:49

GoogleCodeExporter commented 9 years ago
Why can't you use side_effect with patch.object? The side_effect should be 
attached to the *mock* (either on creation or after). Whether it is done 
through patch or patch.object is irrelevant.

Original comment by fuzzyman on 28 Jun 2011 at 3:51

GoogleCodeExporter commented 9 years ago
Thanks for your comment!

I am trying to use the attached code for creating different method instances 
but I don't know how to get it right.

from mock import patch, Mock

class DemoClass(object):
    def __init__(self):
        pass

    def something(self):
        pass

if __name__ == "__main__":
    def side_effect(*args, **kwargs):
        return Mock()
    with patch.object(DemoClass, 'something', side_effect=side_effect):
        one = DemoClass()
        two = DemoClass()
        assert one is not two
        assert one.something is not two.something

Original comment by adiroi...@gmail.com on 28 Jun 2011 at 4:12

Attachments:

GoogleCodeExporter commented 9 years ago
In that case you are *not* patching DemoClass itself, you are just patching the 
'something' method on it. So calling DemoClass doesn't touch your mock at all.

Original comment by fuzzyman on 28 Jun 2011 at 4:31