2015-07-21 38 views
0

我試圖用Djocko模擬兩件事: 1.獲取用戶(我們有一個自定義後端,使網絡調用,我想 以避免)2.模擬另一種方法是通過網絡獲取用於密碼重置的令牌。Python模擬,期望str實例MagicMock發現

下面是測試:

@patch('core.views.KagisoUser') 
def test_forgot_password_sends_reset_email(self, MockKagisoUser): # noqa 
    email = '[email protected]' 
    user = MagicMock() 
    user.email = email 
    user.generate_reset_password_token.return_value = email 
    MockKagisoUser.objects.first.return_value = user 
    data = {'email': email} 
    client = Client() 

    response = client.post('/forgot_password/', data, follow=True) 
    message = list(response.context['messages'])[0].message 

    assert response.status_code == 200 
    assert 'You will receive an email with reset instructions shortly' \ 
     == message 

    assert len(mail.outbox) == 1 
    assert mail.outbox[0].to[0] == email 
    assert mail.outbox[0].subject == 'Password Reset' 
    assert mail.outbox[0].alternatives[0] # HTML body 

我得到這個錯誤:

self = <django.core.mail.message.EmailMultiAlternatives object at 0x7f52eacd3390> 

     def message(self): 
      encoding = self.encoding or settings.DEFAULT_CHARSET 
      msg = SafeMIMEText(self.body, self.content_subtype, encoding) 
      msg = self._create_message(msg) 
      msg['Subject'] = self.subject 
      msg['From'] = self.extra_headers.get('From', self.from_email) 
    >  msg['To'] = self.extra_headers.get('To', ', '.join(self.to)) 
    E  TypeError: sequence item 0: expected str instance, MagicMock found 

下面是執行:

def forgot_password(request): 
    reset_message = 'You will receive an email with reset instructions shortly' 
    not_found_message = 'We could not find a user for that email address' 

    if request.method == 'POST': 
     form = forms.ForgotPasswordForm(request.POST) 

     if form.is_valid(): 
      email = form.cleaned_data['email'] 
      user = KagisoUser.objects.filter(email=email).first() 

      if user: 
       print(user.email) 
       token = user.generate_reset_password_token() 
       url = request.build_absolute_uri(reverse('reset_password')) 
       message = render_to_string(
        'core/emails/reset_password.html', 
        { 
         'url': url, 
         'token': token, 
         'user_id': user.id 
        } 
       ) 
       send_mail(
        'Password Reset', 
        '', 
        '[email protected]', 
        [user.email], 
        html_message=message 
       ) 
       messages.success(request, reset_message) 
       return HttpResponseRedirect('/') 
      else: 
       messages.error(request, not_found_message) 
       return HttpResponseRedirect(reverse('forgot_password')) 
    else: 
     form = forms.ForgotPasswordForm() 

    return render(
     request, 
     'core/auth/forgot_password.html', 
     {'form': form} 
    ) 

我在做什麼錯?

回答

1

堆棧跟蹤將是非常有用的...

但除此之外,似乎你莫克出MockKagisoUser.objects.first而你的看法會從KagisoUser.objects.filter(email=email).first()所以你錯過filter

mock_filter = MagicMock() 
mock_filter.first.return_value = user 
MockKagisoUser.objects.filter.return_value = mock_filter 

上述應用戶返回給你一個過濾器,當你獲得first時,它將返回你的用戶,而你的用戶將返回你的視圖而不是返回MagicMock實例