Home Ask Login Register

Developers Planet

Your answer is one click away!

C_Rod_27 February 2016

How do I mock a file object with a set size?

I have a function that raises an exception if the size of a file is too big (> 1MB). I would like to test this function without using a real image. I know it is possible to mock file objects with mock_open but how do I give this fake file a size?

Here is the function I want to test:

def _check_image_size(img_path):
    megabyte = 1048576

    if os.path.getsize(img_path) > megabyte:
        raise ValueError("Image must be less than or equal to 1MB in size.")

So just to reiterate the question in a different way: how to I test this function without using a real file greater than 1MB in size?

P.S. Should I even write a test for this function? I am very much a new developer who doesn't have much experience. Am I going overboard by wanting to test this?

Answers


jsbueno February 2016

If you are testing this, you should mock os.path.getsize instead - the file object mocked with unittest.mock provides a read method, maybe write, close and other file object specific functions - but this function makes a system stat call to an actual file on the filesystem: the mocked file-object can't be "seen" on the filesystem.

So, the thing to do is instead to trust os.path.getsize works, and mock its return values to "True" and "False" to write the tests you want.


chepner February 2016

It's simpler to mock the function itself.

with mock.patch('os.path.getsize', return_value=2*1024*1024)
    try:
        _check_image_size("any arbitrary string")
    except ValueError:
        print "Successfully raised ValueError"
    else:
        print "Did not raise ValueError"

Or, without using the mock library (or something similar), monkey patch the function directly.

import os.path

os.path.getsize = lambda path: return 2*1024*1024
try:
    _check_image_size("any arbitrary string")
except ValueError:
    print "Successfully raised ValueError"
else:
    print "Did not raise ValueError"


Yoav Glazner February 2016

mock is your friend

import unittest
from unittest.mock import patch
import os

def _check_image_size(img_path):
    megabyte = 1048576

    if os.path.getsize(img_path) > megabyte:
        raise ValueError("Image must be less than or equal to 1MB in size.")

class Test(unittest.TestCase):

    @patch("os.path.getsize")
    def test_getsize(self, getsize):
        getsize.return_value =  1024 ** 2 + 4

        self.assertRaises(ValueError,lambda: _check_image_size("some path to a big* file"))

I think its OK to test a function like this one.

Post Status

Asked in February 2016
Viewed 1,504 times
Voted 5
Answered 3 times

Search




Leave an answer


Quote of the day: live life