Вызывайте исключение с помощью mock при вызове определенной модели Django

У меня есть представление на основе класса, наследующее от FormView с переопределенным методом form_valid(), который я хотел бы протестировать.

Как видите, form_valid() требуется для доступа к модели CustomUser, которая обернута с помощью try и except.

Я пытаюсь вызвать исключение при каждом вызове create_user, но у меня ничего не получается.

Пользователь CustomUser был создан обычным способом через CustomUserManager с методом create_user.


CustomUser = get_user_model()

class SignUpView(FormView):
    template_name = 'accounts/signup.html'
    form_class = SignUpForm

    def form_valid(self, form):

        try:
            self.user = CustomUser.objects.filter(email=form.cleaned_data['email']).first()

            if not self.user:

                self.user = CustomUser.objects.create_user(email=form.cleaned_data['email'],
                                                           full_name=form.cleaned_data['full_name'],
                                                           password=form.cleaned_data['password'],
                                                           is_verified=False
                                                           )
            else:
                if self.user.is_verified:

                    self.send_reminder()

                    return super().form_valid(form)

            self.send_code()
        except:
            messages.error(self.request, _('Something went wrong, please try to register again'))
            return redirect(reverse('accounts:signup'))

        return super().form_valid(form)

Что я пробовал:

  def test_database_fail(self):
        with patch.object(CustomUserManager, 'create_user') as mock_method:
            mock_method.side_effect = Exception(ValueError)

        view = SignUpView.as_view()
        url = reverse('accounts:signup')
        data = {'email': 'test@test.com', 'full_name': 'Test Tester', 'password': 'Abnm1234'}
        request = self.factory.post(url, data)
        request.session = {}
        request.messages = {}
        response = view(request)

и ..

  def test_database_fail(self):
       
        CustomUser = Mock()

        CustomUser.objects.create_user.side_effect = CustomUser.ValueError

        view = SignUpView.as_view()
        url = reverse('accounts:signup')
        data = {'email': 'test@test.com', 'full_name': 'Test Tester', 'password': 'Abnm1234'}
        request = self.factory.post(url, data)
        request.session = {}
        request.messages = {}
        response = view(request)

В обоих случаях исключение не срабатывает.

Мой вопрос заключается в том, как я могу поднять исключение при вызове create_user с использованием mock?

Вам необходимо написать весь тест под mock.patch менеджером контекста. Иначе после завершения оператора with mock больше не работает и не имеет никакого эффекта. Попробуйте следующее:

def test_database_fail(self):
    with patch.object(CustomUserManager, 'create_user') as mock_method:
        mock_method.side_effect = Exception(ValueError)

        view = SignUpView.as_view()
        url = reverse('accounts:signup')
        data = {'email': 'test@test.com', 'full_name': 'Test Tester', 'password': 'Abnm1234'}
        request = self.factory.post(url, data)
        request.session = {}
        request.messages = {}
        response = view(request)

Также обратите внимание, что вы можете указать side_effect непосредственно в методе patch.object:

with patch.object(CustomUserManager, 'create_user', side_effect=Exception):
    # rest of your code
Вернуться на верх