["python","unit-testing","mocking","nose"]
Why python mock patch doesn't work?

I have two files spike.py class T1(object): def foo(self, afd): return "foo" def get_foo(self): return self.foo(1) def bar(): return "bar" test_spike.py: from unittest import TestCase import unittest from mock import patch, MagicMock from spike import T1, bar class TestStuff(TestCase): @patch('spike.T1.foo', MagicMock(return_value='patched')) def test_foo(self): foo = T1().get_foo() self.assertEqual('patched', foo) @patch('spike.bar') def test_bar(self, mock_obj): mock_obj.return_value = 'patched' bar = bar() self.assertEqual('patched', bar) if __name__ == "__main__": unittest.main() When I run python test_spike.py, the first test case would pass, but the second would fail. and I switch to use nosetests test_spike.py, then both two are failed. I don't understand how this happened? These cases supposed to pass all.
For test_foo you are not using patch correctly. You should be using it like this: class TestFoo(TestCase): @patch.object(T1, 'foo', MagicMock(return_value='patched')) def test_foo(self): foo = T1().get_foo() self.assertEqual('patched', foo) that gives me: nosetests test_spike.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Now the second example does not work because you import bar function (get a reference to it) and then try to mock it. When you mock something you can't change what your variables hold (reference to original function). To fix this you should use @falsetru suggested method like: from unittest import TestCase import unittest from mock import patch import spike class TestFoo(TestCase): @patch('spike.bar') def test_bar(self, mock_obj): mock_obj.return_value = 'patched' value = spike.bar() self.assertEqual('patched', value) if __name__ == "__main__": unittest.main() this gives me: python test_spike.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK But when I try to run it with nose I get: nosetests test_spike.py F ====================================================================== FAIL: test_bar (src.test_spike.TestFoo) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/zilva/envs/test/local/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched return func(*args, **keywargs) File "/home/zilva/git/test/src/test_spike.py", line 11, in test_bar self.assertEqual('patched', value) AssertionError: 'patched' != 'bar' ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1) This happends because I am patching not in the right place. My directory structure is: test/ └── src/ ├── spike.py ├── test_spike.py └── __init__.py and I run tests from src directory so I should be patching using path from project root directory like: @patch('src.spike.bar') and this would give me: nosetests test_spike.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK or if I am at test directory: nosetests src/test_spike.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK