在python 2.7中模拟带有一长串调用的静态函数调用

时间:2018-09-12 04:44:29

标签: python python-2.7 testing mocking

我正在尝试测试一个大型的旧版Django应用程序,但由于从未在大型Python应用程序上工作过,我对Python模拟感到困惑。

具体来说,我的方法内部有一条很长的调用链,可以生成一个数组:

def update(self): # in some class X
    # ...
    for z in foo.models.Bar.objects.filter(x=1).select('xyz'):
        raise Exception("mocked successfully")

我想嘲笑foo.models.Bar.objects.filter(x=1).select('xyz')

尝试1

我尝试了从各种问题中收集的几种方法,特别是使用装饰器:

@mock.patch('foo.models.Bar.objects.filter.select')
def test_update(self, mock_select):
    mock_select.return_value = [None]
    X().update()

我从没打过模拟呼叫的内部,但是-由于引发异常,测试应该失败。

尝试2

@mock.patch('foo.models.Bar')
def test_update(self, mock_Bar):
    mock_Bar.objects.filter(x=1).select('xyz').return_value = [None]
    X().update()

尝试3

@mock.patch('foo.models.Bar')
def test_update(self, mock_Bar):
    mock_Bar.objects.filter().select().return_value = [None]
    X().update()

尝试4

然后,我尝试了一些更基本的方法,以查看是否可以获得NPE,但该方法也不起作用。

@mock.patch('foo.models.Bar')
def test_update(self, mock_Bar):
    mock_Bar.return_value = None
    X().update()

我所有的尝试都通过了测试,而不是像我期望的那样触发异常。

太晚了,所以我想我必须在所看到的示例中忽略一些基本知识!?

1 个答案:

答案 0 :(得分:1)

我能够通过嘲笑对象来传递它。尝试3即将结束,您只需将其更改为filter.return_value.select.return_value即可通过。这是我的建议,但似乎嘲笑.objects是首选方式。

@mock.patch('foo.models.Bar.objects')
def test_update(self, mock_bar_objects):
    mock_bar_objects.filter.return_value.select.return_value = [None]
    X().update()

编辑:测试运行输出:

ERROR: test_update (test_x.TestDjango)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/wholevinski/.virtualenvs/p2/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "/home/wholevinski/so_test/django_mock/test/test_x.py", line 10, in test_update
    X().update()
  File "/home/wholevinski/so_test/django_mock/foo/x_module.py", line 6, in update
    raise Exception("mocked successfully")
Exception: mocked successfully

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)