Python 模拟:如何测试递归函数的调用次数? [英] Python mocking: How to test the number of calls on a recursive function?

查看:70
本文介绍了Python 模拟:如何测试递归函数的调用次数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个递归函数存在于一个名为 test_module

I have a recursive function living in a module called test_module

import requests    

def send_msg(msg, retries=0):
    try:
        # send the message here, e.g. a http request
        response = requests.get("http://www.doesnotexist98734.com")
        # if url does not exist raise an exception
    except Exception as e:
        if retries == 0:
            raise e
        else:
            return send_msg(msg, retries=retries-1)

我的问题是如何编写一个单元测试来检查 send_msg 函数在我设置 retries = n 时被调用了 n 次.我正在玩模拟模块(我使用的是 python 2.7),我想我想要这样的东西,

My question is how can I write a unittest that checks the send_msg function is called n times when I set retries = n. I was playing around with the mock module (I'm using python 2.7) and I think I want something a bit like this,

import mock, unittest

class MyUnitTest(unittest.TestCase):

    @mock.patch('test_module.send_msg')
    def test_send_msg_tries_n_times(self, mock_send_msg):
        with self.assertRaises(Exception):
            mock_send_msg("hello", retries=3)
        self.assertEqual(mock_send_msg.call_count, 4) # initial call + 3 retries

但是,由于我已经模拟了该函数,因此它不会调用真正的函数,因此我不会收到异常,也不会递归调用自身...

However since I have mocked the function it won't call the real function so I don't get an exception nor does it call itself recursively...

推荐答案

您不能模拟被测函数.您想测试预期结果,而不是函数是否正确使用递归.

You can't mock the function under test. You want to test for expected results, not if the function used recursion correctly.

模拟 request.get() 调用,让它总是产生异常.然后计算你的模拟被调用的频率.

Mock the request.get() call, and have it always produce an exception. Then count how often your mock was called.

@mock.patch('requests.get')
def test_send_msg_tries_n_times(self, req_get_mock):
    req_get_mock.side_effect = Exception
    with self.assertRaises(Exception):
        send_msg("hello", retries=3)
    self.assertEqual(req_get_mock.call_count, 4)  # 1 initial call + 3 retries

如果将来您想避免使用递归并希望使用迭代,您的测试仍然可以正常工作,因为它验证了行为,而不是具体的实现.您可以安全地重构被测函数.

If in future you want to avoid using recursion and want to use iteration instead, your test still will work as it validates the behaviour, not the specific implementation. You can safely refactor the function-under-test.

这篇关于Python 模拟:如何测试递归函数的调用次数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆