如何通过 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>