简体   繁体   中英

AttributeError: 'dict' object has no attribute 'url'

I'm writing some API tests in pytest which take in a user object which is generated from a utility class. Then it calls the requests library to make the required API calls.

Below is my code that tests the /user operations.

import requests

class users:
    def __init__(self, user_with_token):
        self.token = user_with_token["Token"]
        self.url = 'http://127.0.0.1:5000/api/Users/'
        self.headers = {'token': self.token}

    def get_all_users(self):
        return requests.get(self.url, headers=self.headers).status_code

    def delete_user(self):
        return requests.delete(self.url, headers=self.headers).text

    def update_user(self):
        return requests.post(self.url, headers=self.headers).text

Here are the tests that call the above:

import pytest
from endpoints.users import users

def get_all_users(user_with_token):
    result = users.get_all_users(user_with_token)
    assert result == 200

def test_delete_all_users(user_with_token):
    result = users.delete_user(user_with_token)
    assert "Current user deleted" in result

Here is the definition that generates fake data for the test to consume:

def generate_user_with_token():
    fake = Faker()
    url = 'http://127.0.0.1:5000/api/Register/'

    username = fake.name().split(' ', 1)[0],
    email = fake.email(),
    password = fake.random_int(min=0, max=9999)
    token = requests.post(url, json={'Username': username,'Email Address': email,'Password': password}).text.split()[-2]

    user = {
        "Username": username,
        "Email Address": email,
        "Password": password,
        "Token": token
    }

    return user

When I run it, however. I am receiving an error stating:

    def delete_user(self):
>       return requests.delete(self.url, headers=self.headers).text
E       AttributeError: 'dict' object has no attribute 'url'

Am I unable to use self.url ? I wanted to not have to redeclare it in each defination as the endpoint is the same for each test.

You are calling the delete_user function on the entire class, rather than a specific instance of the class. Also it is more common to make class names uppercase, so the class name would be Users rather than user . To create an instance of the Users class, you would do users = Users(user_with_token) .

When you call the delete_user function on the class (rather than an instance of the class) using users.delete_user(user_with_token) , the user_with_token dict is being passed as the self parameter to the method, which is where the error is coming from. When you instead call the function on a specific instance, Python will automatically make the self parameter be the instance.

When you use the class you should do something like the following (this code is assuming you have renamed your class from users to Users btw:

from endpoints.users import users

def get_all_users(user_with_token):
    users = Users(user_with_token)
    result = users.get_all_users()
    assert result == 200

def test_delete_all_users(user_with_token):
    users = Users(user_with_token)
    result = users.delete_user()
    assert "Current user deleted" in result

Notice that instead of users.delete_user(user_with_token) , the method is simply called with users.delete_user() , as your delete_user method is only expecting a single parameter - self , not two ( self , and user_with_token ). Once you have created an instance of the Users class, it will include the data from user_with_token so there is no need to also pass that data to the delete_user and get_all_users functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM