26、订单管理功能测试与序列化器创建

订单管理功能测试与序列化器创建

1. 订单管理功能测试

1.1 获取所有订单功能测试

对于 get_all_orders_by_customer 方法,需要进行以下测试:
- 给定客户 ID 时,返回的订单数量是否正确。
- 向方法传递无效参数时,是否抛出正确的异常。

def test_get_all_orders_by_customer(self):
    orders = Order.objects.get_all_orders_by_customer(customer_id=1)
    self.assertEqual(2, len(orders),
                     msg='It should have returned 2 orders.')

def test_get_all_order_by_customer_with_invalid_id(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_all_orders_by_customer('o')

1.2 获取客户未完成订单测试

get_customer_incomplete_orders 方法返回给定客户 ID 下状态不为 “Completed” 的所有订单。需要验证:
- 方法返回的项目数量是否正确,以及返回的项目状态是否不等于 “Completed”。
- 传递无效值作为参数时,是否抛出异常。

def test_get_customer_incomplete_orders(self):
    orders = Order.objects.get_customer_incomplete_orders(customer_id=1)
    self.assertEqual(1, len(orders))
    self.assertEqual(Status.Received.value, orders[0].status)

def test_get_customer_incomplete_orders_with_invalid_id(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_customer_incomplete_orders('o')

1.3 获取客户已完成订单测试

get_customer_completed_order 方法返回给定客户 ID 下状态为 “Completed” 的所有订单。测试场景与获取未完成订单类似。

def test_get_customer_completed_orders(self):
    orders = Order.objects.get_customer_completed_orders(customer_id=1)
    self.assertEqual(1, len(orders))
    self.assertEqual(Status.Completed.value, orders[0].status)

def test_get_customer_completed_orders_with_invalid_id(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_customer_completed_orders('o')

1.4 按状态获取订单测试

get_order_by_status 函数根据给定状态返回订单列表。需要测试:
- 给定特定状态时,方法是否返回正确数量的订单。
- 传递无效参数时,是否抛出正确的异常。

def test_get_order_by_status(self):
    order = Order.objects.get_orders_by_status(Status.Received)
    self.assertEqual(2, len(order),
                     msg=('There should be only 2 orders '
                          'with status=Received.'))
    self.assertEqual('customer_001@test.com',
                     order[0].order_customer.email)

def test_get_order_by_status_with_invalid_status(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_orders_by_status(1)

1.5 按时间段获取订单测试

get_order_by_period 方法根据给定的开始和结束日期返回订单列表。需要进行以下测试:
- 传递参数,返回该时间段内创建的订单。
- 传递已知无订单创建的有效日期,返回空结果。
- 传递无效开始日期时,是否抛出异常。
- 传递无效结束日期时,是否抛出异常。

def test_get_orders_by_period(self):
    date_from = timezone.now() - relativedelta(days=1)
    date_to = date_from + relativedelta(days=2)
    orders = Order.objects.get_orders_by_period(date_from, date_to)
    self.assertEqual(3, len(orders))
    date_from = timezone.now() + relativedelta(days=3)
    date_to = date_from + relativedelta(months=1)
    orders = Order.objects.get_orders_by_period(date_from, date_to)
    self.assertEqual(0, len(orders))

def test_get_orders_by_period_with_invalid_start_date(self):
    start_date = timezone.now()
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_orders_by_period(start_date, None)

def test_get_orders_by_period_with_invalid_end_date(self):
    end_date = timezone.now()
    with self.assertRaises(InvalidArgumentError):
        Order.objects.get_orders_by_period(None, end_date)

1.6 设置订单下一个状态测试

set_next_status 方法用于设置订单的下一个状态。需要进行以下测试:
- 调用 set_next_status 时,订单是否获得下一个状态。
- 传递状态为 “Completed” 的订单时,是否抛出异常。
- 传递无效订单时,是否抛出异常。

def test_set_next_status(self):
    order = Order.objects.get(pk=1)
    self.assertTrue(order is not None,
                    msg='The order is None.')
    self.assertEqual(Status.Received.value, order.status,
                     msg='The status should have been Status.Received.')
    Order.objects.set_next_status(order)
    self.assertEqual(Status.Processing.value, order.status,
                     msg='The status should have been Status.Processing.')

def test_set_next_status_on_completed_order(self):
    order = Order.objects.get(pk=2)
    with self.assertRaises(OrderAlreadyCompletedError):
        Order.objects.set_next_status(order)

def test_set_next_status_on_invalid_order(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.set_next_status({'order': 1})

1.7 设置订单状态测试

set_status 方法用于为给定订单设置状态。需要进行以下测试:
- 设置状态,验证订单状态是否真的改变。
- 为已完成的订单设置状态,是否抛出 OrderAlreadyCompletedError 异常。
- 为已取消的订单设置状态,是否抛出 OrderAlreadyCancelledError 异常。
- 调用 set_status 方法时使用无效订单,是否抛出 InvalidArgumentError 异常。
- 调用 set_status 方法时使用无效状态,是否抛出 InvalidArgumentError 异常。

def test_set_status(self):
    order = Order.objects.get(pk=1)
    Order.objects.set_status(order, Status.Processing)
    self.assertEqual(Status.Processing.value, order.status)

def test_set_status_on_completed_order(self):
    order = Order.objects.get(pk=2)
    with self.assertRaises(OrderAlreadyCompletedError):
        Order.objects.set_status(order, Status.Processing)

def test_set_status_on_cancelled_order(self):
    order = Order.objects.get(pk=1)
    Order.objects.cancel_order(order)
    with self.assertRaises(OrderAlreadyCancelledError):
        Order.objects.set_status(order, Status.Processing)

def test_set_status_with_invalid_order(self):
    with self.assertRaises(InvalidArgumentError):
        Order.objects.set_status(None, Status.Processing)

def test_set_status_with_invalid_status(self):
    order = Order.objects.get(pk=1)
    with self.assertRaises(InvalidArgumentError):
        Order.objects.set_status(order, {'status': 1})

2. 创建订单模型序列化器

2.1 创建序列化器文件

在主应用目录下创建一个名为 serializers.py 的文件,并添加以下导入语句:

import functools
from rest_framework import serializers
from .models import Order, OrderItems, OrderCustomer

2.2 创建 OrderCustomerSerializer

class OrderCustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderCustomer
        fields = ('customer_id', 'email', 'name', )

2.3 创建 OrderItemSerializer

class OrderItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderItems
        fields = ('name', 'price_per_unit', 'product_id', 'quantity', )

2.4 创建 OrderSerializer

class OrderSerializer(serializers.ModelSerializer):
    items = OrderItemSerializer(many=True)
    order_customer = OrderCustomerSerializer()
    status = serializers.SerializerMethodField()

    class Meta:
        depth = 1
        model = Order
        fields = ('items', 'total', 'order_customer',
                  'created_at', 'id', 'status', )

    def get_status(self, obj):
        return obj.get_status_display()

    def _create_order_item(self, item, order):
        item['order'] = order
        return OrderItems(**item)

    def create(self, validated_data):
        validated_customer = validated_data.pop('order_customer')
        validated_items = validated_data.pop('items')
        customer = OrderCustomer.objects.create(**validated_customer)
        validated_data['order_customer'] = customer
        order = Order.objects.create(**validated_data)
        mapped_items = map(
            functools.partial(
                self._create_order_item, order=order), validated_items
        )
        OrderItems.objects.bulk_create(mapped_items)
        return order

2.5 序列化器创建流程

graph TD;
    A[创建 serializers.py 文件] --> B[导入必要模块];
    B --> C[创建 OrderCustomerSerializer];
    C --> D[创建 OrderItemSerializer];
    D --> E[创建 OrderSerializer];
    E --> F[实现 get_status 方法];
    E --> G[实现 _create_order_item 方法];
    E --> H[实现 create 方法];

通过以上步骤,我们完成了订单管理功能的测试以及订单模型序列化器的创建,为后续创建 API 端点做好了准备。

3. 订单管理功能测试总结

3.1 测试方法总结

测试方法 测试目的 测试场景
test_get_all_orders_by_customer 验证给定客户 ID 时返回的订单数量是否正确 传入有效客户 ID,检查返回订单数量
test_get_all_order_by_customer_with_invalid_id 验证传递无效参数时是否抛出正确异常 传入无效客户 ID,检查是否抛出 InvalidArgumentError
test_get_customer_incomplete_orders 验证获取客户未完成订单的功能 传入有效客户 ID,检查返回订单数量和状态
test_get_customer_incomplete_orders_with_invalid_id 验证传递无效参数时是否抛出正确异常 传入无效客户 ID,检查是否抛出 InvalidArgumentError
test_get_customer_completed_orders 验证获取客户已完成订单的功能 传入有效客户 ID,检查返回订单数量和状态
test_get_customer_completed_orders_with_invalid_id 验证传递无效参数时是否抛出正确异常 传入无效客户 ID,检查是否抛出 InvalidArgumentError
test_get_order_by_status 验证按状态获取订单的功能 传入有效状态,检查返回订单数量和客户信息
test_get_order_by_status_with_invalid_status 验证传递无效参数时是否抛出正确异常 传入无效状态,检查是否抛出 InvalidArgumentError
test_get_orders_by_period 验证按时间段获取订单的功能 传入有效时间段,检查返回订单数量;传入无订单时间段,检查返回空结果
test_get_orders_by_period_with_invalid_start_date 验证传递无效开始日期时是否抛出异常 传入无效开始日期,检查是否抛出 InvalidArgumentError
test_get_orders_by_period_with_invalid_end_date 验证传递无效结束日期时是否抛出异常 传入无效结束日期,检查是否抛出 InvalidArgumentError
test_set_next_status 验证设置订单下一个状态的功能 传入有效订单,检查状态是否更新
test_set_next_status_on_completed_order 验证传递已完成订单时是否抛出异常 传入已完成订单,检查是否抛出 OrderAlreadyCompletedError
test_set_next_status_on_invalid_order 验证传递无效订单时是否抛出异常 传入无效订单,检查是否抛出 InvalidArgumentError
test_set_status 验证设置订单状态的功能 传入有效订单和状态,检查状态是否更新
test_set_status_on_completed_order 验证为已完成订单设置状态时是否抛出异常 传入已完成订单和状态,检查是否抛出 OrderAlreadyCompletedError
test_set_status_on_cancelled_order 验证为已取消订单设置状态时是否抛出异常 传入已取消订单和状态,检查是否抛出 OrderAlreadyCancelledError
test_set_status_with_invalid_order 验证使用无效订单设置状态时是否抛出异常 传入无效订单和状态,检查是否抛出 InvalidArgumentError
test_set_status_with_invalid_status 验证使用无效状态设置订单状态时是否抛出异常 传入有效订单和无效状态,检查是否抛出 InvalidArgumentError

3.2 测试的重要性

通过对订单管理功能的各项测试,我们可以确保系统在不同输入情况下的稳定性和正确性。例如,在实际业务中,可能会遇到客户输入错误的 ID 或者状态,通过异常处理测试,我们可以保证系统不会因为这些错误输入而崩溃,而是能够给出明确的错误提示。同时,对正常业务流程的测试,如获取订单、设置订单状态等,能够保证系统在日常使用中的准确性,提高用户体验。

4. 序列化器详细解析

4.1 序列化器的作用

序列化器在 Django REST Framework 中起着重要的作用,它可以将复杂的数据类型(如 Django 模型实例)转换为 Python 原生数据类型,以便能够轻松地将其渲染为 JSON、XML 等格式。同时,它也可以将传入的 JSON 数据反序列化为 Django 模型实例,方便进行数据库操作。

4.2 OrderSerializer 详细解析

4.2.1 字段定义
  • items :使用 OrderItemSerializer 进行序列化, many=True 表示这是一个列表字段。
  • order_customer :使用 OrderCustomerSerializer 进行序列化。
  • status :使用 SerializerMethodField ,通过 get_status 方法返回订单状态的显示名称。
4.2.2 Meta
  • depth :设置为 1,表示在序列化时会深入一层关系,获取订单关联的客户和商品信息。
  • model :指定序列化的模型为 Order
  • fields :指定需要序列化和反序列化的字段。
4.2.3 get_status 方法
def get_status(self, obj):
    return obj.get_status_display()

该方法用于返回订单状态的显示名称,而不是存储在数据库中的数值。

4.2.4 _create_order_item 方法
def _create_order_item(self, item, order):
    item['order'] = order
    return OrderItems(**item)

该方法是一个辅助方法,用于创建 OrderItems 实例,并将订单关联到商品上。

4.2.5 create 方法
def create(self, validated_data):
    validated_customer = validated_data.pop('order_customer')
    validated_items = validated_data.pop('items')
    customer = OrderCustomer.objects.create(**validated_customer)
    validated_data['order_customer'] = customer
    order = Order.objects.create(**validated_data)
    mapped_items = map(
        functools.partial(
            self._create_order_item, order=order), validated_items
    )
    OrderItems.objects.bulk_create(mapped_items)
    return order

该方法在调用 save 方法时自动调用,用于创建订单及其关联的客户和商品。具体步骤如下:
1. 从 validated_data 中弹出 order_customer items 数据。
2. 创建 OrderCustomer 实例。
3. 将创建的 OrderCustomer 实例添加到 validated_data 中。
4. 创建 Order 实例。
5. 使用 map functools.partial 方法将 validated_items 转换为 OrderItems 实例列表。
6. 使用 bulk_create 方法批量创建 OrderItems 实例。
7. 返回创建的 Order 实例。

4.3 序列化器创建步骤总结

  1. 创建 serializers.py 文件。
  2. 导入必要的模块。
  3. 创建 OrderCustomerSerializer
  4. 创建 OrderItemSerializer
  5. 创建 OrderSerializer ,并定义字段和 Meta 类。
  6. 实现 get_status 方法。
  7. 实现 _create_order_item 方法。
  8. 实现 create 方法。
graph LR;
    A[定义字段] --> B[定义 Meta 类];
    B --> C[实现 get_status 方法];
    C --> D[实现 _create_order_item 方法];
    D --> E[实现 create 方法];

通过以上步骤,我们完成了订单管理功能的测试和订单模型序列化器的创建,为后续创建 API 端点奠定了基础。在实际开发中,我们可以根据这些测试和序列化器,进一步完善订单管理系统的功能,提高系统的稳定性和可维护性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值