承接 silasyudi/inject-mocks 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

silasyudi/inject-mocks

Composer 安装命令:

composer require silasyudi/inject-mocks

包简介

Automatic injection of mocks into test subjects via #InjectMocks and #Mock annotations, to speed up unit testing with PHPUnit.

README 文档

README

Tests Maintainability Test Coverage

Automatic injection of mocks into test subjects via #InjectMocks and #Mock annotations, to speed up unit testing with PHPUnit.

Summary

Language / Idioma

Leia a versão em português 🇧🇷 aqui.

Instalation

To install in the development environment:

composer require --dev silasyudi/inject-mocks

Requirements

  • PHP 8.3+
  • Composer 2

Features

Using #InjectMocks and #Mock annotations in test classes you can automatically inject mocks into test subjects.

In a typical scenario, we would do it like this:

Example without #InjectMocks/#Mock:

class SomeTest extends \PHPUnit\Framework\TestCase
{
    public void testSomething() 
    {
        $someDependency = $this->createMock(Dependency::class);    
        $anotherDependency = $this->createMock(AnotherDependency::class);
        ...
        $subject = new Service($someDependency, $anotherDependency, ...);
        ...    
    }
    
    ...

This approach brings the difficulty of maintenance, because if the test subject is changed, either by adding, decreasing or replacing the dependencies, you will have to change it in each test.

With the #InjectMocks/#Mock annotations, we abstract these test subject changes. Example:

Example with #InjectMocks/#Mock:

use SilasYudi\InjectMocks\InjectMocks;
use SilasYudi\InjectMocks\Mock;
use SilasYudi\InjectMocks\MockInjector;

class SomeTest extends \PHPUnit\Framework\TestCase
{
    #[Mock]
    private Dependency $someDependency;
    #[Mock]
    private AnotherDependency $anotherDependency;
    
    ...
    
    #[InjectMocks]
    
    public function setUp() : void 
    {
        MockInjector::inject($this);
    }
    
    public void testSomething()
    {
        // $this->subject e as dependências já estão instanciadas.
    }
    
    ...

Usage

As in the example in the previous topic, the #InjectMocks attribute must be placed on the property of the test subject that you want to test, and the #Mock attribute must be placed on the properties corresponding to the dependencies that you want to mock or inject.

After that, run the injector service with the sentence MockInjector::inject($this). This execution can be declared in each test or in setUp.

After executing the injector, the service annotated with #InjectMocks will be a real instance available in the scope of the test class, and each dependency annotated with #Mock will be an instance of MockObject, injected into the test subject via the constructor, and will also be available in the scope of the test class.

Details

1. Scope of Attributes

  • Both #InjectMocks and #Mock MUST be placed over a TYPED property in a TestCase class;
  • Properties that receive #InjectMocks and #Mock attributes MUST be an object;
  • You MUST use only one #InjectMocks attribute per TestCase. When using more than one on the same scope, this library will use only the first one, and ignore the others;
  • You MUST use a #Mock attribute for each test subject dependency you want to mock;
  • Using attributes on untyped properties or on primitive types will cause a MockInjectException exception.
  • When using #Mock on more than one object of the same type in the same test class, this library will match each one via property names, which MUST be identical to the test subject class.

2. Behaviors

#InjectMocks and #Mock work independently and alone, or together. Details about each one:

2.1. #InjectMocks

It will create a real instance through the constructor, and if there are parameters in the constructor, the following value will be used in each parameter, in this order:

  • A mock created from the #[Mock] attribute, if one exists;
  • The default value if it is an optional parameter;
  • null if it is typed as null;
  • Will create a mock if it is not a primitive type. In this case, this mock will not be injected in the TestCase scope;
  • Finally, if the previous options are not satisfied, it will throw MockInjectException exception.

Obs.: You can use #Mock attribute on all, some or none of the test subject's dependencies.

2.2. #Mock

Will create a mock injected into the TestCase scope, without using the constructor. This creation behavior is identical to TestCase::createMock().

silasyudi/inject-mocks 适用场景与选型建议

silasyudi/inject-mocks 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 11.9k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2022 年 05 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「annotations」 「phpunit」 「tests」 「mocks」 「testing-tools」 「inject-mocks」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 silasyudi/inject-mocks 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 silasyudi/inject-mocks 我们能提供哪些服务?
定制开发 / 二次开发

基于 silasyudi/inject-mocks 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 11.9k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 20
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-05-14