Проверьте экземпляр метода Mocked, вызванный один раз

Моя функция ищет объект Actor в базе данных и вызывает его метод do_something() с переданным аргументом.

from my_app.models import Actor

def my_function(id, stuff):
    actor = Actor.objects.get(id=id)
    return actor.do_something(stuff)

Я хочу, чтобы мой модульный тест проверял две вещи:
1. my_function находит нужный Actor.
2. my_function вызывает метод do_something актера, как и ожидалось.

from unittest import mock
from django.test import TestCase
from my_app.models import Actor
from my_app.views import my_function


class ViewsTestCase(TestCase):

    @classmethod
    def setUpTestData(cls):
        self.actor = Actor.objects.create(id=42, name='John')

    def test_my_function(self):
        with mock.patch.object(Actor, 'do_something') as mock_do:
            my_function(id=42, stuff='a-short-string')
            mock_do.assert_called_once_with('a-short-string')

Это работает, чтобы убедиться, что my_function позвонил do_something, как я хотел, но я не знаю, как убедиться, что он нашел Актера, которого я попросил его найти. Этот тест пройдет, даже если my_function найдет не того актера. Есть ли способ это проверить?


person mer-sublime    schedule 01.04.2020    source источник


Ответы (1)


Во-первых, я не уверен, что это лучшая практика утверждения self параметра издевательского метода.

Добавив autospec=True к вашему фиктивному оператору, сам параметр self станет доступным в фиктивном объекте call_args. Чтобы быть более понятным, ваш тестовый пример будет выглядеть примерно так:

from unittest import mock
from django.test import TestCase
from my_app.models import Actor
from my_app.views import my_function


class ViewsTestCase(TestCase):

    @classmethod
    def setUpTestData(cls):
        self.actor = Actor.objects.create(id=42, name='John')

    def test_my_function(self):
        with mock.patch.object(Actor, 'do_something', autospec=True) as mock_do:
                                                      ^^^^^^^^^^^^^
            my_function(id=42, stuff='a-short-string')
            mock_do.assert_called_once_with(self.actor, 'a-short-string')
person partizaans    schedule 01.04.2020
comment
Это именно то, что мне нужно, Autospeccing сделал параметр self доступным в издевательском методе, как вы сказали. Спасибо за вашу помощь. Я также узнал, что кто-то еще спросил об этом и получил этот ответ: object-in-python" title="как вызвать себя в фиктивном методе объекта в python"> stackoverflow.com/questions/20257252/ - person mer-sublime; 02.04.2020