Mocking 模拟对象

未匹配的标注

谈到单元测试时,你总是希望测试一段代码。但是你的代码可能依赖于 API 等第三方服务,你不想在本地测试期间调用它或者在你的 CI 环境中。这时候你应该使用模拟来模拟外部部分或你不想测试的部分。

Masonite 为某些依赖第三方服务的功能提供了一些模拟功能。
对于其他部分或你自己的代码,你可以使用 unittest.mock 标准模块提供的 Python 模拟功能。

Masonite 功能模拟

Masonite 测试用例有两个辅助方法 fake()restore()

你可以通过执行 self.fake(feature) 来模拟 Masonite 功能,然后通过调用 self.restore(feature)将其恢复为真实功能行为。当一个特性被模拟时,真正的行为不会被调用,而是运行一个快速简单的实现,通常提供检查和测试发生的事情的能力。

(目前)可以模拟的可用功能是:

模拟邮件

当模拟电子邮件时,它会阻止电子邮件被真正发送。通常,发送邮件与你实际测试的代码无关。最有可能的是,简单地断言 Masonite 被指示发送给定的可邮寄就足够了。

下面是一个如何模拟在测试中发送的电子邮件的示例:

def setUp(self):
    super().setUp()
    self.fake("mail")

def tearDown(self):
    super().tearDown()
    self.restore("mail")

def test_mock_mail(self):
    welcome_email = self.application.make("mail").mailable(Welcome()).send()
    (
        welcome_email.seeEmailContains("Hello from Masonite!")
        .seeEmailFrom("joe@masoniteproject.com")
        .seeEmailCountEquals(1)
    )

可用的断言有:

  • seeEmailWasSent()
  • seeEmailWasNotSent()
  • seeEmailCountEquals(count)
  • seeEmailTo(string)
  • seeEmailFrom(string)
  • seeEmailReplyTo(string)
  • seeEmailBcc(string)
  • seeEmailCc(string)
  • seeEmailSubjectEquals(string)
  • seeEmailSubjectContains(string)
  • seeEmailSubjectDoesNotContain(string)
  • seeEmailContains(string)
  • seeEmailDoesNotContain(string)
  • seeEmailPriority(string)

模拟通知

模拟通知时,通知不会被真正地发送。通常,发送通知与您实际测试的代码无关。最有可能的是,简单地断言 Masonite 被指示发送给定通知就足够了。

这是一个如何在测试中模拟发送通知的示例:

def setUp(self):
    super().setUp()
    self.fake("notifications")

def tearDown(self):
    super().tearDown()
    self.restore("notifications")

def test_mock_notification(self):
    notification = self.application.make("notification")
    notification.assertNothingSent()
    notification.route("mail", "test@mail.com").send(WelcomeNotification())
    notification.route("mail", "test@mail.com").send(WelcomeNotification())
    notification.assertCount(2)
def test_mock_notification(self):
    self.application.make("notification").route("mail", "test@mail.com").route(
        "slack", "#general"
    ).send(OrderNotification(10))
    self.application.make("notification").assertLast(
        lambda user, notif: (
            notif.assertSentVia("mail")
            .assertEqual(notif.order_id, 10)
            .assertEqual(
                notif.to_slack(user).get_options().get("text"),
                "Order 10 has been shipped !",
            )
        )
    )

可用的断言有:

  • assertNothingSent()
  • assertCount(count)
  • assertSentTo(notifiable, notification_class, callable_assert=None, count=None)
  • assertLast(callable_assert)
  • assertNotSentTo(notifiable, notification_class)

在通知实例上的可用断言:

  • assertSentVia(*drivers)
  • assertEqual(value, reference)
  • assertNotEqual(value, reference)
  • assertIn(value, container)

可用的助手函数有:

  • resetCount()
  • last()

基本的 Python 模拟

要模拟 Python 中的任何代码片段,您可以使用标准的 unittest.mock 模块。你可以在unittest documentation找到更多信息 。

下面是基本示例

from unittest.mock import patch

with patch("some.module") as SomeClass:
    SomeClass.return_value.my_method.return_value = 0
    self.assertEqual(SomeClass().my_method(), 0)

对于模拟外部 HTTP 请求,您可以使用 responses 模块。你可以在responses documentation找到更多信息。

import responses

@responses.activate
def test_mock_third_party_api(self):
    responses.add(responses.POST, "api.github.com", body=b"Ok")
    # 你的业务代码
    self.assertTrue(responses.assert_call_count("api.github.com", 1))

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/masonite/4.0/te...

译文地址:https://learnku.com/docs/masonite/4.0/te...

上一篇 下一篇
贡献者:3
讨论数量: 0
发起讨论 只看当前版本


暂无话题~