26

I'm using Python's mock library. I know how to mock a class instance method by following the documentation:

>>> def some_function():
...     instance = module.Foo()
...     return instance.method()
...
>>> with patch('module.Foo') as mock:
...     instance = mock.return_value
...     instance.method.return_value = 'the result'
...     result = some_function()
...     assert result == 'the result'

However, tried to mock a class instance variable but doesn't work (instance.labels in the following example):

>>> with patch('module.Foo') as mock:
...     instance = mock.return_value
...     instance.method.return_value = 'the result'
...     instance.labels = [1, 1, 2, 2]
...     result = some_function()
...     assert result == 'the result'

Basically I want instance.labels under some_function get the value I want. Any hints?

Kyle F Hartzenberg
  • 2,567
  • 3
  • 6
  • 24
clwen
  • 20,004
  • 31
  • 77
  • 94

1 Answers1

32

This version of some_function() prints mocked labels property:

def some_function():
    instance = module.Foo()
    print instance.labels
    return instance.method()

My module.py:

class Foo(object):

    labels = [5, 6, 7]

    def method(self):
        return 'some'

Patching is the same as yours:

with patch('module.Foo') as mock:
    instance = mock.return_value
    instance.method.return_value = 'the result'
    instance.labels = [1,2,3,4,5]
    result = some_function()
    assert result == 'the result

Full console session:

>>> from mock import patch
>>> import module
>>> 
>>> def some_function():
...     instance = module.Foo()
...     print instance.labels
...     return instance.method()
... 
>>> some_function()
[5, 6, 7]
'some'
>>> 
>>> with patch('module.Foo') as mock:
...     instance = mock.return_value
...     instance.method.return_value = 'the result'
...     instance.labels = [1,2,3,4,5]
...     result = some_function()
...     assert result == 'the result'
...     
... 
[1, 2, 3, 4, 5]
>>>

For me your code is working.

twil
  • 6,032
  • 1
  • 30
  • 28
  • 1
    It doesn't work. I got the same result as `instance.labels = [1, 1, 2, 2]`, which is this mocked variable didn't get used by `some_function`. In the documentation it's mocking out method instead of variable. – clwen Jul 18 '13 at 20:53
  • Updated my answer. Now I'm lost because your code is working. – twil Jul 18 '13 at 21:53
  • In my code, `labels` only appears after calling some function. And that function is called within the function I want to test. Maybe that's the reason. I end up mock out the initialization of the class so that it returns the mock object with behavior i want. – clwen Jul 24 '13 at 06:36
  • I want to raise an exception when I'm dule.Foo instance is created. So I tried both mock.side_effect and mock.return_value. Both didn't work. Why? – Hussain Sep 19 '15 at 18:48
  • That's a different question and there is no code we can look at, but I guess this question is what you are looking for http://stackoverflow.com/questions/28305406/mocking-a-function-to-raise-an-exception-to-test-an-except-block – twil Sep 20 '15 at 10:50