在unittest中覆盖python function-local变量 [英] override python function-local variable in unittest

查看:142
本文介绍了在unittest中覆盖python function-local变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在python(2.7)中有一个执行foo的方法,如果foo不起作用,则会在5分钟后放弃.

I have a method in python (2.7) that does foo, and gives up after 5 minutes if foo didn't work.

def keep_trying(self):
    timeout = 300  #empirically derived, appropriate timeout
    end_time = time.time() + timeout
    while (time.time() < end_time):
        result = self.foo()
        if (result == 'success'):
            break
        time.sleep(2)
    else:
        raise MyException('useful msg here')

我知道foo()可能会产生一些结果,因此我正在使用模拟来伪造那些返回值.问题是,我不希望测试在看到异常之前运行5分钟.

I know some possible results from foo(), so I am using mock to fake those return values. The problem is, I don't want the test to run 5 minutes before it gets to see the exception.

是否有一种方法可以覆盖超时的本地值?我希望只有几秒钟,这样我就可以看到循环尝试几次,然后放弃并加薪.

Is there a way to override that local value of timeout? I'd like that to be just a few seconds so that I can see the loop try a couple times, then give up and raise.

以下内容无效:

@patch.object(myClass.keep_trying, 'timeout')
@patch.object(myClass, 'foo')
def test_keep_trying(self, mock_foo, mock_timeout):
    mock_foo.return_value = 'failed'
    mock_timeout.return_value = 10 # raises AttributeError
    mock_timeout = 10 # raises AttributeError
    ...

推荐答案

您不想模拟timeout的值,而是希望模拟time.time()的返回值.

Rather than trying to mock the value if timeout, you'll want to mock the return value of time.time().

例如

@patch.object(time, 'time')
def test_keep_trying(self, mock_time):
    mock_time.side_effect = iter([100, 200, 300, 400, 500, 600, 700, 800])
    ...

现在第一次调用time.time()时,您将获得100的值,因此,在while循环几圈后,它应该超时.您还可以模拟time.sleep并仅计算调用它的次数,以确保部分代码正常工作.

Now the first time time.time() is called, you'll get the value of 100, so it should timeout when after a few turns of your while loop. You can also mock time.sleep and just count how many times it gets called to make sure that part of the code is working properly.

另一种方法(与上面的方法不完全正交)是允许用户将可选的超时关键字传递给该函数:

Another approach (which isn't completely orthogonal to the one above) is to allow the user to pass an optional timeout keyword to the function:

def keep_trying(self, timeout=300):
    ...

这使您可以指定测试中想要的任何超时(以及以后不想等待5分钟的代码;-).

This allows you to specify whatever timeout you want in the tests (and in future code which doesn't want to wait 5 minutes ;-).

这篇关于在unittest中覆盖python function-local变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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