允许在运行测试时“默认模拟”某些函数的实用程序。

automock的Python项目详细描述


用法

pip install automock

简介

关键思想是,我们为每个想要成为的函数定义一个"模拟工厂" 自动锁定的当调用时没有参数,工厂应该返回一个合适的 允许大多数测试通过的"默认"模拟。默认的模拟工厂是 只需从模拟库中调用magicmock即可。

注册要模拟的函数很简单:

importautomockautomock.register('services.users.client.get_user')

默认情况下,这将提供一个magicmock,相当于装饰所有的magicmock。 您的测试用例具有:

@mock.patch('services.users.client.get_user')

(有关更多情况,请参见下面的 自定义模拟工厂

要做到这一点,您只需要做两件事。

  1. 您需要确保包含 automock.register的模块 调用在测试运行之前被导入。为了达到这个目的,我们有一个 自动模拟注册导入 配置设置。它应该包含字符串路径 到包含注册调用的模块,例如:

    AUTOMOCK_REGISTRATION_IMPORTS=('services.users.test_mocks','services.products.test_mocks','services.paypal.test_mocks',)
  2. 如果要在pytest下运行测试 那么您就不需要做任何其他事情了-automock注册了一个pytest插件 (在pytest中命名为 automock )确保您的测试用例都运行补丁。

  3. 如果您在另一个测试运行程序下运行,那么您的测试用例需要继承 从我们的一个助手类,例如:

    fromautomockimportAutomockTestCase,AutomockTestCaseMixinclassTestWebViews(AutomockTestCase):...classTestSpecialViews(AutomockTestCaseMixin,MyCustomTestCase):...

    这将确保在测试运行之前应用模拟修补程序,并停止 之后。

    或者,您可以手动启动/停止修补:

    fromunittestimportTestCaseimportautomockclassTestStuff(TestCase):# as a decorator@automock.activate()deftest_stuff(self):# automocks active...# as a context-managerdeftest_other_stuff(self):# automocks inactive...withautomock.activate():# automocks active...# automocks inactive

配置

设置要配置为prim通过一个python文件,比如 作为您现有的django settings.py 。要启动这个,有两个 控制配置的加载方式:

  • 自动模拟应用程序配置 应该是python模块的导入路径,例如: 自动模拟应用程序配置=django.conf.settings
  • 自动模拟配置名称空间 设置用于从env和 配置文件。默认为 自动模拟

以下配置键可用(并以前缀 automock默认情况下,请参见上面的 automock配置名称空间:

  • <;namespace>;\u registration\u导入 到模块的导入路径列表 包含 automock.register 调用

修补和导入

关于您模拟的路径,需要注意的重要一点是:

这与直接使用mock.patch时有相同的注意事项。即 您必须修补导入路径

例如,如果您这样做:

# mypackage/mymodule.pyfromservices.product.clientimportget_product

当您修补时:

# won't work:patch('services.product.client.get_product')# works:patch('mypackage.mymodule.get_product')

别这样(看这个 博客文章 有关详细信息)。

如果我们希望在默认情况下模拟所有 特定函数的用法,因为我们只注册一条模拟路径。

相反,您需要在 使用要模拟的函数的代码库:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
0

这将确保我们能够:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
1

让它可靠地工作。

注意:

始终导入automock并用作automock.register以确保 只有一个注册表处于活动状态。

定制模拟工厂

很可能您需要做的不仅仅是提供一个简单的magicmock。例如 我们可能希望根据请求中的某些值自定义响应。

在mock.mock中,这是通过"副作用"实现的。所以我们可能想 像这样定义我们的模拟工厂:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
2

注意,我们将自定义模拟工厂作为第二个参数传递给 寄存器

另外,我们可以使用decorator语法:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
3

现在在我们的测试中,我们可以:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
4

(当然,这是一个无用的测试,只是为了演示模拟)

好的。如果我们需要一个特定测试的自定义返回值呢?

好吧,首先常规的mock.patch仍然有效,您可以将其应用于 您的测试用例。

automock还提供了一个swap mock帮助程序,它允许我们利用 我们的定制模拟工厂。

假设我们的工厂是这样的:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
5

在我们的测试中,我们可以:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
6

这里发生的是,swap-mock调用中的 *args,**kwargs 参数 被传递到 do_something_mock 以获取新的mock 然后应用于替代默认值。

我们还可以将其用作上下文管理器:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
7

检查模拟调用

在测试中,通常需要检查是否调用了模拟函数,并且 如果直接使用mock.patch,这很容易 因为它将模拟对象返回给您。

automock提供 get mock帮助程序来实现相同的功能:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
8

测试自动模拟功能

好吧,那么你已经模仿了你的api客户端或者其他什么。你怎么测试被模仿的 如果它们到处都被模仿的话,它们就会发挥作用?

首先,您不能继承那些测试中的automocktestcase。

但是,也许您还有一堆其他的自动模拟程序需要保持不变。

automock提供了一个k 助手:

@mock.patch('services.users.client.get_user',return_value=MockUser(id=1))@mock.patch('services.products.client.get_product',return_value=MockProduct(id=1))@mock.patch('services.paypal.client.make_payment',return_value=PaypalResult('success'))deftest_some_web_view(self,*mocks)
9

(对于进行http调用的函数,我们推荐 响应 库)

在这里,我们取消了对客户机方法的模拟,以便能够正确地测试它 处理来自远程服务的404响应。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
jframe java对象,框架不工作   我无法使用java netbeans存储本地主机(数据库)的数据   启动备忘单测试时出现java I18n问题/异常   java如何在docker容器的Tomcat7中部署war文件   java如何将@JsonSerialize注释应用于lib类属性?   getter setter何时在java中使用get/set方法   javascript我没有用html显示ajax表为什么?   java如何根据列表中的元素对映射中的键进行排序   java如何将DTO映射到现有的JPA实体?   通过并行处理,使不同线程同时发送邮件的java程序   JavaWebSocket服务器:我能识别客户端吗?   基本Java/Android类模板(<?>)   java为什么JavaFX不能在自制的OpenJDK 17下工作?   在手动调整窗口大小之前,swing Java窗口无法正确重新绘制   java应用程序强制关闭。短信广播接收机   java如何在用户设备中知道第二个应用程序是否安装   java tcollector未收集数据。TSDB是空的   java解压缩包含更多嵌套字符串的字符串   使用CMD脚本安装Java