测试生成器功能有奇怪的行为

时间:2019-03-17 00:08:11

标签: python generator pytest yield

我发现与测试生成器功能有关的怪异行为。我想这背后有一个原因,但我不理解是什么。这是我的代码:

class Foo:
    def foo_function(self):
        return range(10)

class Client:
    def __init__(self):
        self.client = Foo()

    def baz(self):
        for i in self.client.foo_function():
            yield i

这是我的考验:

from unittest.mock import patch

from django.test import TestCase

from my_app.my_module.client import Client


class ClientTestCase(TestCase):

    @patch('my_app.my_module.client.Foo')
    def test_baz(self, foo):
        client = Client('')
        client.baz()

        foo().foo_function.assert_called_once()

运行此测试时,我得到AssertionError

AssertionError: Expected 'foo_function' to have been called once. Called 0 times.

这可能只是我的错,但是一旦尝试使用pdb进行调试,我就会看到奇怪的行为。如果将迹线放在foo_function中,我会意识到它永远不会进入其中。因此,将跟踪放在调用并插入之前,给了我GeneratorExit并离开了:

[28] > /app/my_app/my_module/tests/test_client.py(14)test_baz()
-> client.baz()
   6 frames hidden (try 'help hidden_frames')
(Pdb++) step
--Call--
[29] > /app/my_app/my_module/client.py(11)foo_function()
-> def foo_function(self):
   6 frames hidden (try 'help hidden_frames')
(Pdb++) next
GeneratorExit
[29] > /app/my_app/my_module/client.py(11)foo_function()
-> def foo_function(self):
   6 frames hidden (try 'help hidden_frames')
(Pdb++)

我确定它也与模拟无关,因为我一直在进行更改以尝试了解发生了什么,但是我仍然找不到任何原因。有人知道这是怎么回事吗?如果是这样,我如何测试这样的功能?谢谢!

1 个答案:

答案 0 :(得分:0)

调用client.baz()将创建一个生成器。生成器在开始迭代它们之前不会执行任何代码。

client.baz()更改为next(client.baz()),测试将通过。