Reputation: 61
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?
Upvotes: 4
Views: 5064
Reputation: 8066
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.
Upvotes: 0
Reputation: 531948
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"
Upvotes: 4
Reputation: 110516
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.
Upvotes: 1