mardi 28 juin 2016

python mock - patch decorator doesnt work (again)

The problem: I'm trying to write tests with selenium. During user actions, site can perform communication with other services and I try to mock this parts. The code:

accounts.views.py

class RegistrationView(GuestMixin, FormView):
    template_name = 'registration.jinja'
    form_class = RegisterForm

    def get_context_data(self, **kwargs):
        return super(RegistrationView, self).get_context_data(**kwargs)

    def form_valid(self, form):
        return JsonResponse(form.save(self.request), safe=False)

    def form_invalid(self, form):
        return JsonResponse({'errors': form.errors.as_json()}, safe=False)

accounts.forms.py (something like this)

class RegisterForm(forms.Form):

    # some fields...

    class Meta:
        model = User

    def save(self, request):

        activated = not settings.REQUIRE_SMS
        user = User.objects.create_user(...)

        user = authenticate(username=self.cleaned_data.get('tel'), password=self.cleaned_data.get('password'))

        login(request, user)

        if settings.REQUIRE_SMS:
            # XXX kaboom
            user.send_activation()
            Redis.save_user(user)

accounts.models.py

class User(AbstractBaseUser, PermissionsMixin):

   # fields...

    def send_activation(self):

        gateway = sms.SMSGateway()
        sms_code = random.randrange(1000, 9999)

        if gateway.send(self.tel, sms_code):
            self.sms_code = sms_code
            self.code_expiries = now()
            self.is_active = False
            self.save()

            return True
        else:
            return False

accounts.tests.test_selenium.py

class LoginSeleniumTest(StaticLiveServerTestCase):

    # other methods and stuff...

    @patch(u'accounts.forms.User.send_activation')
    def test_registration_no_name(self, mock_send_activation):

        mocked_gateway.return_value = True

        url = reverse('user:registration')
        self.browser.get('%s%s' % (self.live_server_url, url))

        form = self.get_registration_form(username=self.username, email=self.email, phone=self.phone, password=self.password)
        form.click()
        time.sleep(3)

        name_error = self.browser.find_element_by_css_selector('div#register-name > .error.animate')
        self.assertEqual(name_error.text, u'Обязательное поле.')
        self.assertEqual(User.objects.count(), 0)

Problem is that in # XXX kaboom place the user.send_activation method is still unmocked and I cannot get how to make it. I'm getting crazy with it.

Aucun commentaire:

Enregistrer un commentaire