【问题标题】:Is there a way to count how many times a function mock was called with a certain set of arguments?有没有办法计算使用一组参数调用函数模拟的次数?
【发布时间】:2020-05-11 17:56:39
【问题描述】:

我有一个模拟 api 调用的函数,如下所示:

def mocked_api_call(animal = animal, soundtype=soundtype)

    output = make_sound(animal, soundtype)

    return output

目标是让模拟在第二次使用相同的参数集调用时返回不同的输出。例如,我希望第一次调用返回'meow',第二次返回'MEAAAOWWW',第三次调用返回'mew',如下所示:

output = mocked_api_call(animal='cat', soundtype = 'meow')
# outputs 'meow'

output = mocked_api_call(animal='cat', soundtype = 'meow')
# outputs 'MEAAAOWWW'

output = mocked_api_call(animal='cat', soundtype = 'meow')
# outputs 'mew'

补丁用于测试使用调用api的函数的父函数:

def parent_function(**kwargs):
    response = make_sound(animal=animal, soundtype=soundtype)

测试函数通过这样的monkeypatch调用:

@mock.patch('myscript.api_call', side_effect=mocked_api_call) 
def test_parent_function(*args, **kwargs):
    output = parent_function(**kwargs)

但我找不到一种方法来生成取决于函数被调用次数的响应。这是你可以用 pytest 做的事情吗?

【问题讨论】:

  • 那么你想从哪里得到输出呢?它应该是随机的(例如“MEAAAOWWW”来自哪里)?一般情况下,您可能可以使用side_effect,但这取决于您要实现的目标。
  • @MrBeanBremen 我希望输出有所不同,具体取决于它是第一次还是第二次调用该函数。
  • 你看过side_effect吗?
  • @MrBeanBremen - 我有 - 在上面添加了更多详细信息。我希望这会有所帮助。
  • 好的,问题是您在单次测试中需要什么 - 一种特定动物和声音类型的不同输出?

标签: python unit-testing automated-tests pytest


【解决方案1】:

我不完全确定您的测试会是什么样子,但我们假设您想要进行不同的测试,其中调用索引在每个测试中都会重置。以下内容对您来说可能有点过于笼统,具体取决于您的需要 - 如果您只需要这样,您也可以将索引传递给 make_sound

from unittest import mock
import pytest


class TestSounds:
    indexes = {}
    sounds = {
        ('cat', 'meow'): ('meow', 'MEAAAOWWW', 'mew'),
    }

    @classmethod
    def make_sound(cls, animal, soundtype):
        key = (animal, soundtype)
        if key in cls.sounds:
            index = cls.indexes.setdefault(key, 0)
            sound = cls.sounds[key][index]
            cls.indexes[key] = (index + 1) % len(cls.sounds[key])
            return sound

    # if you need the order not be reset in each test, you can change 
    # the scope to "class"
    @pytest.fixture(scope="function", autouse=True)
    def reset_indexes(self):
        self.__class__.indexes = {}

    def test_parent_function(self, **kwargs):
        with mock.patch('myscript.api_call',
                        side_effect=[self.make_sound(**kwargs),
                                     self.make_sound(**kwargs)]):
            output1 = parent_function(**kwargs)
            output2 = parent_function(**kwargs)

请注意,这是未经测试的,但它可能会给你一些想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多