我正在开发 Django 项目,我的测试用例遇到了一些问题。具体来说,我在与用户配置文件更新和用户创建相关的两个测试用例方面遇到问题。
有人可以帮助我确定可能导致这些测试失败的原因以及如何修复它们吗?任何见解或指导将不胜感激。
这是我收到的错误消息:
======================================================================
FAIL: test_update_user_profile (user.tests.test_user_api.PrivateUserApiTests)
Test updating the user profile for the authenticated user.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/app/user/tests/test_user_api.py", line 301, in test_update_user_profile
self.assertEqual(self.profile.bio, payload['profile']['bio'])
AssertionError: 'Profile bio.' != 'Updated bio.'
- Profile bio.
+ Updated bio.
======================================================================
FAIL: test_create_user_success (user.tests.test_user_api.PublicUserApiTests)
Test creating a user is successfull.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/app/user/tests/test_user_api.py", line 95, in test_create_user_success
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
AssertionError: 400 != 201
test_user_api.py
CREATE_USER_URL = reverse('user:create')
ME_URL = reverse('user:me')
def create_user(**params):
return get_user_model().objects.create_user(**params)
def create_profile(user, **params):
defaults = {
'picture': None,
'bio': 'My bio.',
'dob': '2000-12-12',
}
defaults.update(params)
return UserProfile.objects.create(user=user, **defaults)
class PublicUserApiTests(TestCase):
def setUp(self):
self.client = APIClient()
def test_create_user_success(self):
payload = {
'name': 'Test Name',
'email': '[email protected]',
'password': 'testpass123',
'profile': {
'picture': None,
'bio': 'Create bio.',
'dob': '2000-01-01',
}
}
res = self.client.post(CREATE_USER_URL, payload, content_type='application/json')
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
class PrivateUserApiTests(TestCase):
"""Test API requests that require authentication."""
def setUp(self):
self.user = create_user(
name='Test Name',
email='[email protected]',
password='testpass123',
)
self.profile = create_profile(
user=self.user,
picture=None,
bio="Profile bio.",
dob="2017-05-27",
)
self.client = APIClient()
self.client.force_authenticate(user=self.user)
def test_update_user_profile(self):
payload = {
'name': 'Updated Name',
'email': '[email protected]',
'password': 'newpassword123',
'profile': {
'picture': None,
'bio': 'Updated bio.',
'dob': '2022-02-02',
}
}
res_profile = self.client.patch(ME_URL, payload, format='json')
self.user.refresh_from_db
self.profile.refresh_from_db()
self.assertEqual(self.profile.bio, payload['profile']['bio'])
Urls.py:
path('create/', views.CreateUserView.as_view(), name='create'),
path('me/', views.ManageUserView.as_view(), name='me'),
模型.py:
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('User must have an email address.')
user = self.model(email=self.normalize_email(email), **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=225, unique=True)
name = models.CharField(max_length=225)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='userprofile')
picture = models.ImageField(null=True, blank=True, upload_to=image_file_path)
bio = models.CharField(max_length=225, blank=True)
dob = models.DateField()
created_on = models.DateTimeField(auto_now_add=True)
def name(self, value):
self.user.name = value
self.user.save()
def email(self, value):
self.user.email = value
self.user.save()
def __str__(self):
return self.user.email
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Views.py:
class CreateUserView(generics.CreateAPIView):
serializer_class = UserSerializer
class ManageUserView(generics.RetrieveUpdateAPIView):
serializer_class = UserSerializer
authentication_classes = (JWTAuthentication, )
permission_classes = [permissions.IsAuthenticated]
def get_object(self):
return self.request.user
def update(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
序列化器.py:
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ['picture', 'bio', 'dob']
class UserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(source="userprofile", many=False)
class Meta:
model = get_user_model()
fields = ['name', 'email', 'password', 'profile']
extra_kwargs = {'password': {'write_only': True, 'min_length': 5}}
def get_token(self, obj):
token = RefreshToken.for_user(obj)
return str(token.access_token)
def create(self, validated_data):
return get_user_model().objects.create_user(**validated_data)
def update(self, instance, validated_data):
password = validated_data.pop('password', None)
if password:
instance.set_password(password)
instance.save()
profile_data = validated_data.pop('profile', None)
if profile_data is not None:
instance.profile.picture = profile_data['picture']
instance.profile.bio = profile_data['bio']
instance.profile.dob = profile_data['dob']
instance.profile.save()
return super().update(instance, validated_data)
def get_name(self, obj):
return obj.name
def get_id(self, obj):
return obj.id
预先感谢您的协助!
我怀疑这两个错误是相关的。当您应该传递 JSON 字符串时,您正在传递一个 python 对象,例如,
res = self.client.post(CREATE_USER_URL, payload, content_type='application/json')
您需要将
payload
转换为正确的格式才能正常工作。
import json
...
payload_json = json.dumps(payload)
res = self.client.post(CREATE_USER_URL, payload_json, content_type='application/json')