如何在 Laravel 中测试接口的实现
How to test implementations of interfaces in Laravel
我在这里问了一个具体问题:
phpunit error when testing an implementation with injected dependencies
但是,我想知道我遇到的问题是否是结构和设计问题,而不是编码问题。因此,我想在这里问一个更笼统的问题:
我正在使用Laravel,我写了一个接口,然后是支持它的class。然后我使用服务提供商将接口绑定到实现 class 并注入所需的依赖项,这恰好是一个 Eloquent 模型。
我的问题是:我应该如何测试这个 class?目前我正在接口上调用一个方法。因此,这会调用服务提供者来解析实现(而不是接口)并为我注入一个模型(需要工厂构建或模拟)。这感觉我正在测试太多(测试服务提供者和模型,甚至在接触我的目标方法之前)。我应该直接测试实施吗?
完全正确 - 直接测试实现,如果可以的话完全绕过 IoC 容器。
这样想 - 您对接口进行部分编码,以便可以将功能换出(例如 MySQL 数据库驱动程序换成 PostgreSQl 驱动程序)。因此,必须测试 class 的每个单独实现。您不应该依赖 IoC 容器绑定来测试给定的实现,因为它完全依赖于配置。
据我所知,在测试期间唯一可以依赖 IoC 容器解决问题的情况是,如果解决的问题是您正在测试的问题的依赖项,并且:
- 本身已经过全面测试,因此您知道它可以正常工作
- 执行您不希望在测试期间发生的昂贵操作(例如第 3 方 API 操作或破坏性的事情),在这种情况下您应该模拟 class/interface 和 'pretend' 它完成了工作,然后 returns 你指定的东西(也有助于保证依赖组件的输入和输出,所以你可以测试 class 对依赖的响应*)
即便如此,您也可以手动注入依赖项以确保一致的代码环境。 IoC 容器只是帮助深入创建任何依赖项,而不必在测试中担心这一切。
*考虑测试使用 'now' 日期(并确定一个人的年龄,比如说)的东西,但在测试期间无法指定使用什么作为 'now' 日期 - 你在测试期间必须重新实现您的年龄计算代码只是为了计算出年龄,以确保您编写的代码输出正确的年龄,这对实际测试您的代码几乎没有作用!
我在这里问了一个具体问题:
phpunit error when testing an implementation with injected dependencies
但是,我想知道我遇到的问题是否是结构和设计问题,而不是编码问题。因此,我想在这里问一个更笼统的问题:
我正在使用Laravel,我写了一个接口,然后是支持它的class。然后我使用服务提供商将接口绑定到实现 class 并注入所需的依赖项,这恰好是一个 Eloquent 模型。
我的问题是:我应该如何测试这个 class?目前我正在接口上调用一个方法。因此,这会调用服务提供者来解析实现(而不是接口)并为我注入一个模型(需要工厂构建或模拟)。这感觉我正在测试太多(测试服务提供者和模型,甚至在接触我的目标方法之前)。我应该直接测试实施吗?
完全正确 - 直接测试实现,如果可以的话完全绕过 IoC 容器。
这样想 - 您对接口进行部分编码,以便可以将功能换出(例如 MySQL 数据库驱动程序换成 PostgreSQl 驱动程序)。因此,必须测试 class 的每个单独实现。您不应该依赖 IoC 容器绑定来测试给定的实现,因为它完全依赖于配置。
据我所知,在测试期间唯一可以依赖 IoC 容器解决问题的情况是,如果解决的问题是您正在测试的问题的依赖项,并且:
- 本身已经过全面测试,因此您知道它可以正常工作
- 执行您不希望在测试期间发生的昂贵操作(例如第 3 方 API 操作或破坏性的事情),在这种情况下您应该模拟 class/interface 和 'pretend' 它完成了工作,然后 returns 你指定的东西(也有助于保证依赖组件的输入和输出,所以你可以测试 class 对依赖的响应*)
即便如此,您也可以手动注入依赖项以确保一致的代码环境。 IoC 容器只是帮助深入创建任何依赖项,而不必在测试中担心这一切。
*考虑测试使用 'now' 日期(并确定一个人的年龄,比如说)的东西,但在测试期间无法指定使用什么作为 'now' 日期 - 你在测试期间必须重新实现您的年龄计算代码只是为了计算出年龄,以确保您编写的代码输出正确的年龄,这对实际测试您的代码几乎没有作用!