I'm want to mock or stub a function for testing. Not sure if I have the terminology right so correct me if I'm wrong, but I understand a mock as using a mocking library similar to unittest.mock to create a fake object and has expectations about what parameters it will receive and what what it will return, etc. This seems a bit of overkill to me since all I want is the mocked/stubbed method to do is return a set value.
I think of stubbing as just 'mocking without a library', like the answer to this question. From what I can see, this is exactly what I want. It's light and simple and you don't have to mess around with all the options of mocking for the simple cases.
My question is, is it safe to do this? The question above seems to be overwriting the in memory representation of a method, and it just doesn't seem right. Is this accepted by the python community? Or is it encouraged to use a proper mocking library all the time?
EDIT What kind of horrible things would happen if you didn't reassign the method in the finally block, as the linked answer states?
The main reason I wanted to stub the method myself was so that I wouldn't have to worry about a mock and go through setting it up. However I found this blog post which shows an excellent way to use the mock
library with annotations making it a lot easier than creating an instance of Mock
manually. Here is an excerpt:
rm.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import os.path
def rm(filename):
if os.path.isfile(filename):
os.remove(filename)
rmtest.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import rm
import mock
import unittest
class RmTestCase(unittest.TestCase):
@mock.patch('mymodule.os.path')
@mock.patch('mymodule.os')
def test_rm(self, mock_os, mock_path):
# set up the mock
mock_path.isfile.return_value = False
rm("any path")
# test that the remove call was NOT called.
self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
# make the file 'exist'
mock_path.isfile.return_value = True
rm("any path")
mock_os.remove.assert_called_with("any path")