如何通过 pytest 自定义 HTTPError 并在测试阶段引发它以查看方法是否可以处理它?
How to customize an HTTPError via pytest and raise it while testing phase to see whether a method could handle it?
我使用 pytest 并尝试在测试阶段引发异常以测试该方法是否可以处理该异常。但似乎它总是通过,即使我删除了 try...except... 块。
这是class有错误,已经处理
class SaltConfig(GridLayout):
def check_phone_number_on_first_contact(self, button):
s = self.instanciate_ServerMsg(tt)
try:
s.send()
except HTTPError as err:
print("[HTTPError] : " + str(err.code))
return
# some code when running without error
def instanciate_ServerMsg():
return ServerMsg()
这是帮助程序 class,它生成前者 class 使用的 ServerMsg 对象。
class ServerMsg(OrderedDict):
def send(self,answerCallback=None):
#send something to server via urllib.urlopen
这是我的测试代码:
class TestSaltConfig:
def test_check_phone_number_on_first_contact(self):
myError = HTTPError(url="http://127.0.0.1", code=500,
msg="HTTP Error Occurs", hdrs="donotknow", fp=None)
mockServerMsg = mock.Mock(spec=ServerMsg)
mockServerMsg.send.side_effect = myError
mockSalt = mock.Mock(spec=SaltConfig)
mockSalt.instanciate_ServerMsg.return_value = mockServerMsg
mockSalt.check_phone_number_on_first_contact(self, "2")
我认为上面的代码没有多大意义,因为我实际上是在模拟对象上进行测试,但原因是我不知道如何在异常已经存在的情况下调用方法时引发异常已处理。
如何解决?谢谢
这是一个使用 decorator
而不是 Mock library
来实现您的目的的示例。
我稍微修改了您的代码,使其可以在我的环境中运行。
import unittest
def exception_function(f, exception_type):
def exception_fn(*args, **kwargs):
raise exception_type
def fn(*args, **kwargs):
return exception_fn
return fn
def wrap(f, exception_type):
@exception_function(f, exception_type)
def fn(*args, **kwargs):
return f(*args, **kwargs)
return fn
class ServerMsg():
def send(self):
print("send normally")
class SaltConfig():
def check_phone_number_on_first_contact(self):
s = ServerMsg()
try:
s.send()
except ValueError:
print("raise exception")
class TestSaltConfig(unittest.TestCase):
def test_check_phone_number_on_first_contact(self):
s = SaltConfig()
original_method = ServerMsg.send
print (ServerMsg.send) #<unbound method ServerMsg.send>
s.check_phone_number_on_first_contact() #send normally
ServerMsg.send = wrap(ServerMsg.send, ValueError)
print (ServerMsg.send) #<unbound method ServerMsg.exception_fn>
s.check_phone_number_on_first_contact() #raise exception
ServerMsg.send = original_method
print (ServerMsg.send) #<unbound method ServerMsg.send>
我使用 pytest 并尝试在测试阶段引发异常以测试该方法是否可以处理该异常。但似乎它总是通过,即使我删除了 try...except... 块。
这是class有错误,已经处理
class SaltConfig(GridLayout):
def check_phone_number_on_first_contact(self, button):
s = self.instanciate_ServerMsg(tt)
try:
s.send()
except HTTPError as err:
print("[HTTPError] : " + str(err.code))
return
# some code when running without error
def instanciate_ServerMsg():
return ServerMsg()
这是帮助程序 class,它生成前者 class 使用的 ServerMsg 对象。
class ServerMsg(OrderedDict):
def send(self,answerCallback=None):
#send something to server via urllib.urlopen
这是我的测试代码:
class TestSaltConfig:
def test_check_phone_number_on_first_contact(self):
myError = HTTPError(url="http://127.0.0.1", code=500,
msg="HTTP Error Occurs", hdrs="donotknow", fp=None)
mockServerMsg = mock.Mock(spec=ServerMsg)
mockServerMsg.send.side_effect = myError
mockSalt = mock.Mock(spec=SaltConfig)
mockSalt.instanciate_ServerMsg.return_value = mockServerMsg
mockSalt.check_phone_number_on_first_contact(self, "2")
我认为上面的代码没有多大意义,因为我实际上是在模拟对象上进行测试,但原因是我不知道如何在异常已经存在的情况下调用方法时引发异常已处理。
如何解决?谢谢
这是一个使用 decorator
而不是 Mock library
来实现您的目的的示例。
我稍微修改了您的代码,使其可以在我的环境中运行。
import unittest
def exception_function(f, exception_type):
def exception_fn(*args, **kwargs):
raise exception_type
def fn(*args, **kwargs):
return exception_fn
return fn
def wrap(f, exception_type):
@exception_function(f, exception_type)
def fn(*args, **kwargs):
return f(*args, **kwargs)
return fn
class ServerMsg():
def send(self):
print("send normally")
class SaltConfig():
def check_phone_number_on_first_contact(self):
s = ServerMsg()
try:
s.send()
except ValueError:
print("raise exception")
class TestSaltConfig(unittest.TestCase):
def test_check_phone_number_on_first_contact(self):
s = SaltConfig()
original_method = ServerMsg.send
print (ServerMsg.send) #<unbound method ServerMsg.send>
s.check_phone_number_on_first_contact() #send normally
ServerMsg.send = wrap(ServerMsg.send, ValueError)
print (ServerMsg.send) #<unbound method ServerMsg.exception_fn>
s.check_phone_number_on_first_contact() #raise exception
ServerMsg.send = original_method
print (ServerMsg.send) #<unbound method ServerMsg.send>