You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony PHPUnit 6.5:不重构代码Mock静态File::create方法返回指定对象

Mocking Static File::create() Method Without Refactoring Code

I get it—you're stuck trying to mock that static File::create() call in your business code, and the old staticExpects method is deprecated. You don't want to refactor your existing code just to get test coverage, so let's walk through some working alternatives that let you return a predefined File object for your assertions.

Your Scenario Recap

First, let's recap your code to make sure we're on the same page:

Business Code:

public function uploadSingle(array $params, UploadedFile $uploadedFile, FileHolderInterface $owner): File { 
    $file = File::create($filename, $target); 
    // Other business logic here
    return $file; 
}

Current Test Code:

public function testUploadSingleUnit() { 
    $service = $this->createService(); 
    // Prepare test data ($params, $uploadedFile, $location)
    $result = $service->uploadSingle($params, $uploadedFile, $location); 
}

You want $result to be a controlled File object so you can run assertions against it. Here are two solid solutions:


Solution 1: Use Mockery (Most Flexible)

Mockery is a popular mocking library for PHP that makes static method mocking straightforward without refactoring. Here's how to implement it:

  1. Ensure Mockery is installed (it's often included in Laravel/PHP projects, but if not, install via Composer).
  2. Update your test method to mock the static create method and return your predefined File object.
use Mockery;
use PHPUnit\Framework\TestCase;

class YourServiceTest extends TestCase
{
    // Clean up Mockery after each test to prevent leaks
    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public function testUploadSingleUnit()
    {
        // 1. Create the File object you want to return (mock or real)
        // Option A: Mock the File object if you don't need real behavior
        $mockFile = Mockery::mock(File::class);
        // Option B: Use a real File object (e.g., with factory or direct instantiation)
        // $mockFile = File::make(['filename' => 'test.png', 'path' => '/target/path']);

        // 2. Mock the static File::create method
        Mockery::mock('alias:' . File::class)
            ->shouldReceive('create')
            ->once() // Verify the method is called exactly once
            ->withAnyArgs() // Use ->with($expectedFilename, $expectedTarget) to match specific params
            ->andReturn($mockFile);

        // 3. Run your test as normal
        $service = $this->createService();
        // Prepare your test data ($params, $uploadedFile, $location)
        $result = $service->uploadSingle($params, $uploadedFile, $location);

        // 4. Assert the result matches your predefined File object
        $this->assertSame($mockFile, $result);
        // Add any other assertions you need (e.g., verifying business logic ran)
    }
}

The alias: prefix tells Mockery to create an alias mock, which replaces the original File class during the test—no code changes needed in your business logic.


Solution 2: PHPUnit Native Static Mock (No Extra Libraries)

If you prefer sticking with PHPUnit's built-in tools (version 9.5+ supports this), you can mock static methods directly using the MockBuilder. Here's how:

use PHPUnit\Framework\TestCase;

class YourServiceTest extends TestCase
{
    public function testUploadSingleUnit()
    {
        // 1. Create your target File object
        $mockFile = $this->createMock(File::class);
        // Or use a real instance: $mockFile = new File(['filename' => 'test.jpg']);

        // 2. Create a mock of the File class and set up the static method expectation
        $fileMock = $this->getMockBuilder(File::class)
            ->onlyMethods(['create']) // Specify the static method to mock
            ->getMock();

        $fileMock::expects($this->once())
            ->method('create')
            ->withAnyArgs() // Or match specific parameters
            ->willReturn($mockFile);

        // 3. Execute the test
        $service = $this->createService();
        $result = $service->uploadSingle($params, $uploadedFile, $location);

        // 4. Assertions
        $this->assertSame($mockFile, $result);
    }
}

Note: Some older PHPUnit versions might require enabling static mock support, but this works out of the box in recent releases.


Both solutions let you mock the static File::create() call without touching your business code, giving you full control over the returned File object for your assertions.

内容的提问来源于stack exchange,提问作者shuba.ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:24:51