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

无独立服务器下用Behat/Mink测试Symfony 3.4 API的POST请求

Solution for Testing Symfony 3.4 API POST Requests Without a Web Server

Absolutely, you can test POST requests directly through Symfony's internal kernel—no external web server, Docker, or network calls required. Here are two practical approaches tailored to your Behat/Mink + CI/CD workflow:

1. Use Symfony's HttpKernel Directly in Your Behat Context

Behat's SymfonyExtension already gives you access to Symfony's kernel, which lets you simulate HTTP requests internally. You can inject the kernel into your context class and manually craft POST requests with JSON payloads.

First, ensure your context accepts the kernel via dependency injection (add this to your behat.yml if missing):

# behat.yml
default:
  suites:
    default:
      contexts:
        - App\Features\Context\ApiContext:
            kernel: '@kernel'

Then implement the context with methods to send POST requests and validate responses:

<?php
namespace App\Features\Context;

use Behat\Behat\Context\Context;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class ApiContext implements Context
{
    private $kernel;
    private $response;

    public function __construct(KernelInterface $kernel)
    {
        $this->kernel = $kernel;
    }

    /**
     * @When I send a POST request to :path with JSON payload:
     */
    public function iSendAPostRequestToWithJsonPayload(string $path, string $jsonPayload)
    {
        $request = Request::create(
            $path,
            Request::METHOD_POST,
            [],
            [],
            [],
            ['CONTENT_TYPE' => 'application/json'],
            $jsonPayload
        );

        // Handle the request internally using Symfony's kernel
        $this->response = $this->kernel->handle($request);
    }

    /**
     * @Then the response status code should be :statusCode
     */
    public function theResponseStatusCodeShouldBe(int $statusCode)
    {
        if ($this->response->getStatusCode() !== $statusCode) {
            throw new \Exception(sprintf(
                'Expected status code %d, got %d',
                $statusCode,
                $this->response->getStatusCode()
            ));
        }
    }

    /**
     * @Then the response should contain JSON with :key equal to :value
     */
    public function theResponseShouldContainJsonWithEqualTo(string $key, string $value)
    {
        $responseData = json_decode($this->response->getContent(), true);
        if (!isset($responseData[$key]) || $responseData[$key] !== $value) {
            throw new \Exception(sprintf(
                'Expected JSON key "%s" to be "%s", got "%s"',
                $key,
                $value,
                $responseData[$key] ?? 'null'
            ));
        }
    }
}

Now you can write feature files that mirror your existing GET test style but support POST:

@function1
Scenario Outline: Test POST API endpoint
  When I send a POST request to "/api/v1/hello" with JSON payload:
    """
    {"name": "Jay"}
    """
  Then the response is JSON
  And the response status code should be 200
  And the response should contain JSON with "message" equal to "Hello, Jay!"

2. Extend Mink to Support POST Requests (Familiar Syntax)

If you prefer to stick closer to Mink's existing step style, you can leverage the Symfony driver's underlying BrowserKit client to send POST requests internally—no external server needed.

Add this method to your existing Mink-enabled context:

/**
 * @When I send a POST request to :path with JSON:
 */
public function iSendAPostRequestToWithJson(string $path, string $json)
{
    $session = $this->getSession();
    $client = $session->getDriver()->getClient();

    $client->request(
        Request::METHOD_POST,
        $path,
        [],
        [],
        ['CONTENT_TYPE' => 'application/json'],
        $json
    );
}

This works because Mink's Symfony driver uses BrowserKit, which interacts directly with the Symfony kernel. You can pair this with Mink's built-in assertions (like Then the response is JSON) for a seamless experience.

CI/CD Workflow Tips

  • Both approaches run entirely within the PHP process—no need to start Apache, PHP-FPM, or any external server.
  • Add php bin/console cache:clear --env=test to your shell script to ensure a clean test environment.
  • Ensure your CI/CD runner installs all dev dependencies (run composer install without --no-dev).

内容的提问来源于stack exchange,提问作者JayMore

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:54