python 如何在Django中使用Pytest测试认证的POST请求

r1wp621o  于 2023-02-28  发布在  Python
关注(0)|答案(4)|浏览(182)

我想使用Pytest在API上测试一个经过验证的post请求,这是我目前正在做的事情:

def test_auth_user_can_create(self, client):
      
    
    url = api_reverse('crud-simulation_api')

    data = {
        "project": "testproject",
        ....
    }

        response = client.post(url, json=data)
        assert response.status_code == 200

这不起作用,因为它给我一个401(未授权),而不是200。这是有意义的,因为夹具是一个客户端,而不是一个管理客户端。
但是如果我传入admin_client而不是client,它会给我一个错误的请求。虽然我发送的数据应该是好的。
我还尝试像这样传入头(因为我使用JWT授权):

token = "bigassstringwhichismytoken"

headers = {
        "Authorization": "JWT " + token
    }

最后,我尝试登录之前,给我一个403(禁止):

def test_auth_user_can_create_simulation_api(self, client, django_user_model):
     
    username = "Jack"
    password = "password"

    django_user_model.objects.create_user(username=username, password=password)
    client.login(username=username, password=password)

    url = api_reverse('crud-simulation_api')

    data = {
        "project": "testproject",
        ...
    }

    response = client.post(url, json=data)
    assert response.status_code == 200

如果有人能给我指出正确的方向,那就太好了!提前非常感谢

brjng4g3

brjng4g31#

要为client.{request}提供标头,请将它们作为关键字agruments单独传递:

client.post(url, data, HTTP_FIRST_HEADER='...', HTTP_SECOND_HEADER='...')

尽管您不太可能与post调用链中的任何保留参数名冲突,但最好将所有需要的头收集到字典中:

headers = {
    'HTTP_FIRST_HEADER': '...',
    'HTTP_SECOND_HEADER': '...',
}

并将它们作为任意数量的关键字参数传递给request:

client.post(url, data, **headers)

在这种情况下,**参数被视为额外信息,并自动添加为标头。

olqngx59

olqngx592#

你可以用用户名和密码点击登录url并获得令牌。创建一个类似headers = {'Authorization': 'JWT <token>'}的头字典
并且在使用post时使用报头。

client.post(url, json=data, headers=headers)
ecbunoof

ecbunoof3#

我建议安装pytest-django包,根据它的文档,最简单的方法是使用admin_clientfixture,因为admin_client的类型是 django.test.Client,它可以用于get和post请求。

def test_sth_with_auth(admin_client):
    response = admin_client.get('/private')
    assert response.status_code == 200

另外,如果你想使用一个特定的用户,你可以尝试这样的东西:

@pytest.fixture
def my_user(django_user_model):
    return django_user_model.objects.create_user(username=username, password=password)

@pytest.fixture
def logged_in_client(client, my_user):
    return client.force_login(my_user)

def test_sth_with_auth(logged_in_client):
    response = logged_in_client.get('/private')
    assert response.status_code == 200

文档的这一部分可以帮助编写你想要的logged_in_client()。

cl25kdpy

cl25kdpy4#

使用令牌访问:
制作夹具以创建用户:

@pytest.fixture()
def user_token():
    user= User.objects.create_user(username="salah", password="passtest")
    Token.objects.create(user=user)
    return user.auth_token.key

现在,以标题形式发送:

def test_example(client, user_token):
    response = client.get(
        /lists/,
        HTTP_AUTHORIZATION=f"Token {user_token}",
    )

使用HTTP_AUTHORIZATION进行访问。

相关问题