How to mock a method return value of a class

Question:

I want to mock

os.stat(self.tmp_file).st_size

def original_func():
     print (os.stat("test.txt").st_size==35)

I tried this

@mock.patch("os.stat")
def test(os_stat):
    stat = mock.Mock()
    stat.st_size.return_value = 35
    os_stat.return_value = stat
    original_func()

It does not work. The print statement should be true which it is not.

Asked By: Akamad007

||

Answers:

This seems to work

import os
import mock


def original_func():
    print (os.stat("test.txt").st_size == 35)


@mock.patch("os.stat")
def test(os_stat):
    os_stat.return_value = mock.Mock(st_size=35)
    original_func()

test()
Answered By: Akamad007

You can set arbitrary attributes on Mocks.

import os
import mock


def original_func():
    print(os.stat("test.txt").st_size == 35)


@mock.patch("os.stat")
def test(os_stat):
    os_stat.return_value.st_size = 35
    original_func()

test()

If you want an arbitrary attribute on a Mock, just make up a name and set it equal to something. If you want an arbitrary method, make up a name, and set the value of its .return_value to something:

import mock

mocky = mock.Mock()

# create an attribute `foo_attribute` and set it to a string value
mocky.foo_attribute = "hi"
print(mocky.foo_attribute)

# create a method `foo_method()` and set it to return an integer value
mocky.foo_method.return_value = 100
print(mocky.foo_method())

Details

The @mock.patch("os.stat") decorator is mocking os.stat(), the constructor method of the stat class.

os_stat.return_value by default, returns a new Mock object instance that will be substituted for the constructor method’s return value (the stat object instance) – in the scope of def test, which includes the nested function call to original_func.

That os.stat() object that you replace with os_stat.return_value object, has attributes, including st_size, and it is that attribute that you want to set the value of on the mock.

Assigning it the way you have done works, but note that calling return_value attribute on an existing mock already returns a Mock() by default (unless you set it to some value) so setting it to Mock(st_size=35) is not necessary.

Answered By: Davos
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.