Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking the super class calls on python

Tags:

I am doing some unit testing and at some point I need to mock a super call to throw an error, for example:

@classmethod def myfunc(cls, *args, **kwargs)     try:         super(MyClass, cls).my_function(args, kwargs)     except MyException as e:         #... 

I am using the mocker library to mock my objects in general but I haven't found a way to mock this.

like image 391
Hassek Avatar asked Oct 26 '12 19:10

Hassek


People also ask

Can we mock a class in Python?

mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. unittest. mock provides a core Mock class removing the need to create a host of stubs throughout your test suite.

How do you use mock response in Python?

get() should return a mock for the response. To mock the response, you can use the MagicMock class of the unittest. mock module.

What does mocking mean in Python?

What is mocking in Python? Mocking in Python means the unittest. mock library is being utilized to replace parts of the system with mock objects, allowing easier and more efficient unit testing than would otherwise be possible.

What is Side_effect in mock Python?

side_effect: side_effect allows to perform side effects, including raising an exception when a mock is called. patch(): The patch() decorator/ context manager makes it easy to mock classes or objects in a module under test.


2 Answers

Using unittest.mock from the standard library I would do something like this.

In your class definition:

from somelib import ASuperClass  class MyClass(ASuperClass):     def my_cool_method(self):         return super().my_cool_method() 

In the module where you are calling MyClass:

from unittest.mock import patch from mymodule import MyClass  @patch("mypackage.mymodule.ASuperClass.my_cool_method") def call_with_mock(mocked_super):     myinstance = MyClass()     myinstance.my_cool_method()     # do stuff with `mocked_super`  call_with_mock() 
like image 181
antonagestam Avatar answered Sep 21 '22 14:09

antonagestam


I found a way, sort of hacky but it works, I'll explain with my example, this is based on this response so thanks @kindall:

def my_test(self):     import __builtin__     from mocker import Mocker, KWARGS, ARGS      mymocker = mocker.mock()     mymocker.my_function(ARGS, KWARGS)     mocker.throw(MyException)      def mysuper(*args, **kwargs):         if args and issubclass(MyClass, args[0]):             return mymocker         return original_super(*args, **kwargs)      __builtin__.original_super = super     __builtin__.super = mysuper      with mocker:         MyClass.myfunc() 

so essentially what I do is check if the super call is from the class I want to mock, else just do a normal super.

Hope this helps someone :)

like image 22
Hassek Avatar answered Sep 17 '22 14:09

Hassek