@albertalexandrov

Как замокать метод __next__?

Что-то не соображу, как замокать метод `Queue.__next__`:

from unittest.mock import MagicMock


class Queue:

    def __init__(self):
        self.nums = [1, 2, 3] # имитация очереди ibm mq

    def __iter__(self):
        return self

    def __next__(self):
        try:
            num = self.nums.pop()
        except Exception:
            raise StopIteration
        return num


class Consumer:

    def __init__(self, queue):
        self._queue = queue

    def consume(self):
        for msg in self._queue:
            raise ValueError(msg)


def test_it():
    queue = MagicMock()
    queue.__next__.side_effect = [4, 5, 6]  # не работает
    consumer = Consumer(queue)
    consumer.consume()


Интерпретатор даже не делает попытки вызвать __next__.

P.S. Код выше - упрощенный пример реального программного компонента.
  • Вопрос задан
  • 144 просмотра
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Вообще делать return self из __iter__() не очень хорошая идея.
Или верни итератор по внутренней коллекции, т.е. iter(self.nums). Это имеет смысл, так как чтение коллекции циклом for по-хорошему не должно приводить к её модификации. Для этого лучше сделать явный метод.
Или сделай из __iter__() генератор, и делай yield значения.

В обоих случаях определять __next__() не потребуется.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы