Django正在模仿

2024-04-19 00:08:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我在理解mock如何工作以及如何用mock对象编写单元测试时遇到了问题。我想模拟一个外部api调用,这样我就可以为这些函数和使用这些调用的函数编写单元测试。在

起初我试图模拟check_sms_请求,后来我需要用它来覆盖对象的check_delivery_状态。在

如何为这种情况编写测试?在

要模仿的函数

def check_sms_request(remote_id, phone):
    if not can_sms(phone):
        return None

    client = Client(settings.SMS_API_URL)

    base_kwargs = {
        'phone': phone,
        'remoteId': remote_id,
    }
    request = client.service.CheckSmsRequest(settings.SMS_API_LOGIN, settings.SMS_API_PASSWORD, base_kwargs)

    return request

class SMS(models.Model):
    sms_response = models.IntegerField(choices=SMS_SEND_STATUS, null=True, blank=True)
    delivery_status = models.IntegerField(choices=DELIVERY_STATUS_CHOICES, null=True, blank=True)
    has_final_status = models.BooleanField(default=False)

    def check_delivery_status(self):
        if not self.has_final_status:
            response_status = check_sms_request(self.id, self.phone)
            if response_status is not None:
                self.history.create(fbs_status=self.sms_response, delivery_status=response_status.response)
            if response_status is not None and response_status.response in FINAL_STATUSES:
                self.has_final_status = True
            if response_status is not None:
                self.delivery_status = response_status.response
            self.save()
        return self.delivery_status

我的测试:

^{pr2}$

Tags: 函数selfnonetrueifmodelsresponserequest
2条回答
  1. 先测试检查短信请求
    1. 模拟客户端
    2. 使用返回值检索服务和CheckSmsRequest模拟
    3. 呼叫检查短信请求
    4. check Client和CheckSmsRequest使用正确的参数调用了一次
  2. check_sms_请求应该是一个类的方法,将它移到sms模型中,或者只是添加方法并从这个方法调用函数
  3. 在测试check_delivery_状态时模拟此模型方法

型号:

class SMS(models.Model):
    sms_response = models.IntegerField(choices=SMS_SEND_STATUS, null=True, blank=True)
    delivery_status = models.IntegerField(choices=DELIVERY_STATUS_CHOICES, null=True, blank=True)
    has_final_status = models.BooleanField(default=False)

    def check_sms_request(remote_id, phone):
        if not can_sms(phone):
            return None

        client = Client(settings.SMS_API_URL)

        base_kwargs = {
            'phone': phone,
            'remoteId': remote_id,
        }
        request = client.service.CheckSmsRequest(settings.SMS_API_LOGIN, settings.SMS_API_PASSWORD, base_kwargs)

        return request

    def check_delivery_status(self):
        if not self.has_final_status:
            response_status = self.check_sms_request(self.id, self.phone)
            if response_status is not None:
                self.history.create(fbs_status=self.sms_response, delivery_status=response_status.response)
            if response_status is not None and response_status.response in FINAL_STATUSES:
                self.has_final_status = True
            if response_status is not None:
                self.delivery_status = response_status.response
            self.save()
        return self.delivery_status

测试:

^{pr2}$

您可以对测试函数进行monkey-patch,如下所示:

@override_settings(SMS_WHITELIST=['', ], SMS_ENABLE=True)
def test_soap_check_sms_request(self):
    check_sms_request = Mock(return_value=True)
    check_sms_request.response = SMS_SENT_AND_RECIEVED
    self.assertEqual(check_sms_request.response, SMS_SENT_AND_RECIEVED)

    obj = SMS.objects.create(**{
        'phone': self.user.phone,
        'text': u"Hello",
        'user': self.user,
        'site': self.site2,
    })

    import model
    old_fn = model.check_sms_request
    model.check_sms_request = check_sms_request
    obj.check_sms_status()
    model.check_sms_request = old_fn

相关问题 更多 >