Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Patch - Patching the class introduces an extra parameter?

Tags:

First time using patch. I've tried to patch one of my classes for testing. Without the patch attempting to run gets past the test function definition, but with the patch the test function definition apparently requires another parameter and I get a

TypeError: testAddChannelWithNamePutsChannel() takes exactly 1 argument (2 given) 

Error. The test code is the following:

import unittest import mock from notification.models import Channel, addChannelWithName, deleteChannelWithName  class TestChannel(unittest.TestCase):     @mock.patch('notification.models.Channel')     def testAddChannelWithNamePutsChannel(self):         addChannelWithName('channel1')         Channel.put.assert_called_with() 

Why does it require an extra parameter with the patch and what should this parameter be? Thank you much!

like image 309
golmschenk Avatar asked Apr 17 '13 04:04

golmschenk


People also ask

What does patch mean in Python?

What is (monkey-)patching in Python? (monkey-) patching is a technique for changing code behaviour without altering its source. It is done in runtime, usually by overriding attributes of existing objects. An object can be an instance of some sort, a class or even a module.

What does mock patch do?

mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.

What is the difference between mock and MagicMock?

With Mock you can mock magic methods but you have to define them. MagicMock has "default implementations of most of the magic methods.". If you don't need to test any magic methods, Mock is adequate and doesn't bring a lot of extraneous things into your tests.

What is Side_effect in mock Python?

side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.


2 Answers

Patch passes in an instance of the patched object to your test method (or to every test method if you are patching at the class level). This is handy because it lets you set return values and side effects, or check the calls made

from unittest.mock import patch  @patch('some_module.sys.stdout') def test_something_with_a_patch(self, mock_sys_stdout):     mock_sys_stdout.return_value = 'My return value from stdout'      my_function_under_test()      self.assertTrue(mock_sys_stdout.called)     self.assertEqual(output, mock_sys_stdout.return_value) 

If you just want to literally patch something out to ignore it then you can call patch with the following invocation

from unittest.mock import patch, Mock  @patch('some_module.sys.stdout', Mock()) def test_something_with_a_patch(self): 

That replaces sys.stdout in the some_module with a Mock object and does not pass it to the method.

like image 140
aychedee Avatar answered Sep 22 '22 18:09

aychedee


patch passes the patched object to the test function. Its documented here:

patch as function decorator, creating the mock for you and passing it into the decorated function:

>>> >>> @patch('__main__.SomeClass') ... def function(normal_argument, mock_class): ...     print(mock_class is SomeClass) ... >>> function(None) True 
like image 44
aquavitae Avatar answered Sep 24 '22 18:09

aquavitae