我有一个正在进行单元测试的Web应用程序。我正在尝试测试drf序列化程序,但是序列化程序会更改日期时间的格式,因此,格式不同的相同日期由于不相同而无法通过测试。
我尝试格式化序列化器timeDateField,但是他们使用的所有strftime格式都填充了零,而我的测试用户的last-login属性给出的日期没有填充零。我认为解决方案可以以所选答案描述here的方式解决,但这似乎有点粗略,理想情况下,作为一个必须维护此代码的人,我想要一个更清洁或更Python化的解决方案。
这是测试:
class UserTest(TestCase):
def setup(self):
last_login = datetime.datetime(2000, 1, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
date_joined = datetime.datetime(2019, 2, 2, hour=2, minute=2, second=2, microsecond=2, tzinfo=None)
birthdate = timezone.now().date()
renewal = timezone.now().date()
return User.objects.create(username='test_user', first_name='test_first', last_name='test_last',
email='test_mail', last_login=last_login, date_joined=date_joined,
birthdate=birthdate, gender='U', renewal=renewal)
def test_user_serializer(self):
self.u = self.setup()
serializer = UserSerializer(self.u, many=False)
data = serializer.data
.....
# tests for serialized attributes
self.assertEquals((data['last_login']), self.u.last_login) # FAILING THE TEST
这是UserSerializer:
class UserSerializer(serializers.ModelSerializer):
last_login = serializers.DateTimeField
date_joined = serializers.DateTimeField
birthdate = serializers.DateField
renewal = serializers.DateField
class Meta:
model = User
fields = ('__all__')
这是我遇到的错误:
self.assertEquals(data['last_login'], self.u.last_login)
AssertionError: '2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在模型中,last_login属性是dateTimeField。
我应该尝试更改要测试的元素之一的格式,还是有一种方法可以编写一个比较日期的测试,而与格式无关?
请告知。谢谢。
答案 0 :(得分:1)
发生错误的原因是由于您试图对两个不同的数据类型/对象进行比较。在下面的行中:-
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在LHS上,我们有一个字符串( ISO 8601时间戳格式),在RHS中,我们有一个datetime对象。因此,由于数据类型不同,上述操作总是会产生错误。
因此,您有两种选择,或者可以使用strftime()
之类的函数将RHS(日期时间对象)转换为字符串。或者,您可以在LHS(时间戳字符串)之外创建日期时间对象。
我将解释第一种方法,因为这是两种方法中比较容易的一种。
因此,为了将日期时间对象转换为字符串,我们必须通过strftime()
传递它。
strftime()将日期时间对象** /元组作为参数,然后根据格式规范将其转换为字符串。
因此,如果我们通过datetime.datetime(2000, 1, 1, 0, 0)
通过strftime()
并使用ISO 8601格式规范,那么我们将获得所需的格式。
示例:-
import datetime
datet_obj = datetime.datetime(2000, 1, 1, 0, 0)
datet_str = datet_obj.strftime("%Y-%m-%dT%H:%M:%SZ")
print(datet_str)
输出:-
'2000-01-01T00:00:00Z'
通过这种方式,您可以将日期时间对象转换为所需格式的字符串。
现在,如果我们为其全部创建一个衬板,然后进行比较,即
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0).strftime("%Y-%m-%dT%H:%M:%SZ")
由于LHS和RHS相等,上述代码成功运行并输出 False 。
**日期时间对象通常是strptime()
的输出。
答案 1 :(得分:0)
最简单的方法是:
assert response.json()["created_at"] == serializers.DateTimeField().to_representation(instance.created_at)