代码之家  ›  专栏  ›  技术社区  ›  nflacco

在Python2.7中用长链调用模拟静态函数调用

  •  0
  • nflacco  · 技术社区  · 6 年前

    我正在尝试测试一个大型的遗留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 回复  |  直到 6 年前
        1
  •  1
  •   wholevinski    6 年前

    我可以让它通过模拟物体。尝试#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)