无法在Django单元测试中测试密码更改 [英] Can't test password change in Django unittest

查看:83
本文介绍了无法在Django单元测试中测试密码更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为Django应用程序编写集成测试,以测试密码是否已从其他API更改.但是,在调用密码更改API后,无法测试新密码.

I'm trying to write an integration test for a Django application to test if the password was changed from a rest API. However, after calling the password change API, testing for the new password doesn't work.

我在这里做的是:我通过一个电话呼叫将密码更改为johnjohn,然后尝试检查密码是否实际更改

What I'm doing here is: I change the password to johnjohn through a rest call, then try to check if the password is actually changed

我的单元测试文件

import json
import urllib
import urllib2

import requests
from django.contrib.auth.models import User

from django.test import TestCase
from adaptors.redis_class import DjangoRedis


class PasswordChange(TestCase):
    def setUp(self):
        User.objects.create_user(username='john', email='john@john.com', password='john')
        # class for redis access  
        r = DjangoRedis()
        r.set("email:john@john.com", '0' * 40, ex=3600)
        r.set('0' * 40, "email:john@john.com", ex=3600)
    def test_change_password(self):
        # Fake url I set through redis
        url = 'http://127.0.0.1:8000/reset/' + '0' * 40 + '/'
        r = requests.get(url)
        csrf_token = r.content.split('csrf_token')[1].split('"')[2]
        payload = {'csrfmiddlewaretoken': csrf_token, 'payload': json.dumps({'password': 'johnjohn'})}
        headers = {'Cookie': 'csrftoken=' + csrf_token}
        data = urllib.urlencode(payload)
        req = urllib2.Request(url, data, headers)
        response = urllib2.urlopen(req)
        json_res = json.loads(response.read())

        # This doesn't fail
        self.assertEqual(json_res['password_changed'], True)
        u = User.objects.get(username='john')

        # This fails
        self.assertEqual(u.check_password('johnjohn'),True)

我的观点

import hashlib
import random

from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from django.http import JsonResponse
from django.shortcuts import render
from django.views.generic import View

from adaptors.redis_class import DjangoRedis
from constants import PASSWORD_RESET
from tasks import send_email
from util.rest import get_payload
class ResetPage(View):
    def post(self, requests, reset_token):
        r = DjangoRedis()
        token = r.get(reset_token)
        if token is None:
            return JsonResponse({"token": False})
        payload = get_payload(requests.POST)
        try:
            email = token.split(':')[1].lower()
            u = User.objects.get(email=email)
            u.set_password(payload['password'])
            u.save()
            r.delete(reset_token)
            r.delete('email:' + email)
            return JsonResponse({'password_changed': True})
        except ValueError:
            return JsonResponse({"password_changed": False, 'error': "can't get your email from the database (E01)"})
        except ObjectDoesNotExist:
            return JsonResponse({"password_changed": False, 'error': "User doesn't exist (E02)"})

    def get(self, requests, reset_token):
        r = DjangoRedis()
        if not r.get(reset_token):
            raise Http404
        return render(requests, "login/reset.html", {'token': reset_token})

unittests目录中,单元测试文件称为rest_pass_login_tests.py.

The unittest file is called rest_pass_login_tests.py in a unittests directory.

我使用以下命令运行它.

I run it by using the following command.

./manage.py test unittests/ --pattern="rest_pass_login_tests.py"

./manage.py test unittests/ --pattern="rest_pass_login_tests.py"

当我通过浏览器正常测试时,密码更改可以正常进行.但是,当我尝试通过单元测试检查密码是否已更改时,我收到了无效的密码.

When I test normally through the browser, the password change works fine. However, when I try to check if the password was changed or not through a unittest, I get an invalid password.

我在做什么错了?

推荐答案

我正在使用开发服务器运行单元测试.更改密码后,实际上是在发布到开发服务器,而不是测试服务器.

I was using dev server to run unittests. When I changed my password, I was actually posting to the dev server instead of the test one.

这是我的新单元测试

import json

from django.contrib.auth.models import User
from django.test import Client
from django.test import TestCase

from adaptors.redis_class import DjangoRedis


class PasswordChange(TestCase):
    def setUp(self):
        User.objects.create_user(username='john', email='john@john.com', password='john')
        r = DjangoRedis()
        r.set("email:john@john.com", '0' * 40, ex=3600)
        r.set('0' * 40, "email:john@john.com", ex=3600)

    def test_change_password(self):
        c = Client()
        payload = {'payload': json.dumps({'password': 'johnjohn'})}

        url = '/reset/' + '0' * 40 + '/'
        res = c.post(url, payload)
        res = res.json()
        self.assertEqual(res['password_changed'], True)
        u = User.objects.get(username='john')
        self.assertEqual(u.check_password('johnjohn'), True)

如果要使用selenium IDE,请确保您是StaticLiveServerTestCase固有的,而不是unittest.请遵循此示例.另外,不要忘记将变量self.base_url更改为self.live_server_url

If you're going to use selenium IDE, make sure you inherent from StaticLiveServerTestCase instead of unittest. Follow this example. Also, don't forget to change this variable self.base_url to self.live_server_url

这在我的setUp方法中

This inside my setUp method

self.base_url = self.live_server_url

感谢 Fips koterpillar 在IRC频道上为我提供帮助, aks 在我的下方发表评论.

Thanks to fips, koterpillar for helping me on the IRC channel, and aks for commenting under me.

这篇关于无法在Django单元测试中测试密码更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆