簡體   English   中英

如何模擬未按名稱調用的 function?

[英]How can I mock a function that isn't called by name?

假設我有一個裝飾器,它收集它裝飾的所有函數,以便在將來的某個時候調用。

我的裝飾器.py

class CallLater(object):
    funcs = []

    def __init__(self, func):
        self.funcs.append(func)

    @classmethod
    def call_now(cls, *args, **kwargs):
        for func in cls.funcs:
            func(*args, **kwargs)

然后,我在一個模塊中有一個 function,其中一個將由我的裝飾器保存。

我的模塊.py

import logging

from mydecorator import CallLater

logging.basicConfig(level=logging.INFO) 

@CallLater
def log_a():
    logging.info("A")

@CallLater
def log_b():
    logging.info("B")

def log_c():
    logging.info("C")

現在,如果我導入mymodule並調用CallLater.call_now() ,則會調用log_alog_b 但是假設在測試期間,我希望log_blog_c替換。 我會嘗試用模擬進行替換。

模擬測試.py

import logging
import pytest

from mymodule import log_a, log_c
from mydecorator import CallLater

logging.basicConfig(level=logging.INFO) 
pytest_plugins = ('pytest_mock',)

def test_mocking(mocker, caplog):
    mocker.patch('mymodule.log_b', log_c)

    CallLater.call_now()

    logs = [rec.message for rec in caplog.records]
    assert logs == ["A", "C"]

但是當我運行pytest時,我發現我的模擬不起作用。

FAILED mock_test.py::test_mocking - AssertionError: assert ['A', 'B'] == ['A', 'C']

我想'mymodule.log_b'是錯誤的 mocking 目標,因為它沒有被調用為mymodule.log_b() ,但我不確定在這種情況下使用什么來代替。 任何建議表示贊賞!

這是不可能的,問題是函數在加載時已經分配給列表。 我能看到修補這個的唯一方法是直接修補CallLater.funcs ,這有點尷尬,因為你必須手動替換log_blog_c - 但在這里:

import logging
from unittest import mock

from mymodule import log_c
from mydecorator import CallLater

logging.basicConfig(level=logging.INFO)


def test_mocking(caplog):
    funcs = [log_c if f.__name__ == 'log_b' else f for f in CallLater.funcs]
    with mock.patch.object(CallLater, 'funcs', funcs):
        CallLater.call_now()

        logs = [rec.message for rec in caplog.records]
        assert logs == ["A", "C"]

請注意,您不能直接與 function (例如f == log_b )進行比較,因為log_b是修飾的 function,而不是 ZC1C425268E68385D1AB5074C17A94F1 中保存的CallLater.funcs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM