Django: метод создания фиктивной модели - PullRequest
0 голосов
/ 11 марта 2019

У меня есть модель под названием Работа.И я сделал файл services.py, куда я собираюсь поместить некоторые методы и бизнес-логику.Я пытаюсь проверить их с помощью Mock.Проблема в том, что если я хочу издеваться над Job.objects.create, он выдает ошибку.

services.py

from .models import Job
class CreateJob:                                                    

    def __init__(                                                   
        self,                                                       
        title,                                                      
        email,                                                      
    ):                                                              
        self._title = title                                         
        self._email = email                                         

    def execute(self):                                              
        # Create dictionary with the keys without the first _ in the name
        params = {k[1:] if k[0] == '_' else k:v for k,v in self.__dict__.items() if v is not None}
        job = Job.objects.create(**params)
        return job

Это тест micase, и он запускается ОК

class TestExecute(TestCase):                     
    def setUp(self):                             
        self._use_case = CreateJob(              
            title='How to test a job creation',  
            email='john.smith@example.com',      
        )                                        

    def test_return_job_type(self):              
        result = self._use_case.execute()        
        assert isinstance(result, Job)           

Но если Я хочу пропатчить метод создания , чтобы я не попадал в базу данных, как это

def create_job(params):                                     
    return Job(**params)                                    

@patch.object(Job.objects, 'create', side_effect=create_job)
class TestExecute(TestCase):                                
    def setUp(self):                                        
        self._use_case = CreateJob(                         
            title='How to test a job creation',             
            email='john.smith@example.com',                 
        )                                                   

    def test_return_job_type(self,mock_create):             
        result = self._use_case.execute()                   
        assert isinstance(result, Job)

У меня следующая ошибка: TypeError: create_job () получил неожиданный аргумент ключевого слова 'title'

А вот и след:

services.py:100: in execute
job = Job.objects.create(**params)
/usr/lib/python3.6/unittest/mock.py:939: in __call__
return _mock_self._mock_call(*args, **kwargs)
def _mock_call(_mock_self, *args, **kwargs):
    self = _mock_self
    self.called = True
    self.call_count += 1
    _new_name = self._mock_new_name
    _new_parent = self._mock_new_parent

    _call = _Call((args, kwargs), two=True)
    self.call_args = _call
    self.call_args_list.append(_call)
    self.mock_calls.append(_Call(('', args, kwargs)))

    seen = set()
    skip_next_dot = _new_name == '()'
    do_method_calls = self._mock_parent is not None
    name = self._mock_name
    while _new_parent is not None:
        this_mock_call = _Call((_new_name, args, kwargs))
        if _new_parent._mock_new_name:
            dot = '.'
            if skip_next_dot:
                dot = ''

            skip_next_dot = False
            if _new_parent._mock_new_name == '()':
                skip_next_dot = True

            _new_name = _new_parent._mock_new_name + dot + _new_name

        if do_method_calls:
            if _new_name == name:
                this_method_call = this_mock_call
            else:
                this_method_call = _Call((name, args, kwargs))
            _new_parent.method_calls.append(this_method_call)

            do_method_calls = _new_parent._mock_parent is not None
            if do_method_calls:
                name = _new_parent._mock_name + '.' + name

        _new_parent.mock_calls.append(this_mock_call)
        _new_parent = _new_parent._mock_new_parent

        # use ids here so as not to call __hash__ on the mocks
        _new_parent_id = id(_new_parent)
        if _new_parent_id in seen:
            break
        seen.add(_new_parent_id)

    ret_val = DEFAULT
    effect = self.side_effect
    if effect is not None:
        if _is_exception(effect):
            raise effect

        if not _callable(effect):
            result = next(effect)
            if _is_exception(result):
                raise result
            if result is DEFAULT:
                result = self.return_value
            return result
           ret_val = effect(*args, **kwargs)
E           TypeError: create_job() got an unexpected keyword argument 'title'

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Вы должны определить принятые параметры для метода create_job.На данный момент он принимает только 1 параметр с именем params.Вы должны написать это так:

def create_job(**params):                                     
    return Job(**params)

И для python принято использовать *args и **kwargs, хотя их не требуется использовать.

0 голосов
/ 11 марта 2019

Глупая ошибка, функция, которая исправляет метод создания, должна быть такой:

def create_job(**params):                                     
    return Job(**params) 

Обратите внимание на два ** на параметре определения функции

...