我正在做一些单元测试,在某些时候我需要模拟一个super
调用以引发错误,例如:
@classmethod
def myfunc(cls, *args, **kwargs)
try:
super(MyClass, cls).my_function(args, kwargs)
except MyException as e:
#...
我正在使用mocker库来模拟我的对象,但我还没有找到一种方法来模拟它。
我正在做一些单元测试,在某些时候我需要模拟一个super
调用以引发错误,例如:
@classmethod
def myfunc(cls, *args, **kwargs)
try:
super(MyClass, cls).my_function(args, kwargs)
except MyException as e:
#...
我正在使用mocker库来模拟我的对象,但我还没有找到一种方法来模拟它。
从标准库中使用unittest.mock
我会做这样的事情。
在你的类定义中:
from somelib import ASuperClass
class MyClass(ASuperClass):
def my_cool_method(self):
return super().my_cool_method()
在您调用的模块中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()
我找到了一种方法,有点老套,但它有效,我会用我的例子来解释,这是基于这个响应,所以感谢@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()
所以本质上我所做的是检查super
调用是否来自我想模拟的类,否则就做一个正常的super
.
希望这可以帮助某人:)
如果有人需要另一种方法来解决这个模拟:
# some_package/some_module.py
class MyClass(SuperClass):
def some_function(self):
result_super_call = super().function()
# test_file.py
@patch('some_package.some_module.super')
def test_something(self, mock_super):
obj = MyClass()
mock_super().some_function.return_value = None
使用 Python 3.6
@Markus 正在寻找正确的地方。只要您进行单元测试(即只有一次调用super
),您就可以模拟__builtin__.super
如下:
with mock.patch('__builtin__.super') as mock_super:
mock_super.side_effect = TypeError
with self.assertRaises(TypeError):
obj.call_with_super()
Python 自己的 Mock 类提供了一个可以帮助解决此问题的spec
参数:
with mock.patch('...ParentClass.myfunc') as mocked_fn:
mocked_fn.side_effect = MyException() # Parent's method will raise
instance = mock.Mock(spec=MyClass) # Enables using super()
MyClass.myfunc(instance) # Will enter your `except` block
好吧,那你需要mockmy_function
超类的方法MyClass
来炸掉。