| sidebar_position | 10 |
|---|
This guide helps you resolve common issues when using PHP Swagger Test.
For detailed information about exceptions and how to handle them, see Exception Handling.
Full Error:
Request body provided for 'GET /pet/{petId}' but the OpenAPI 3.0 specification
does not define a request body for this operation.
Suggestion: Either remove the request body from your test using withRequestBody(),
or add a 'requestBody' definition to your OpenAPI specification for this endpoint.
Cause: You're sending a request body for an operation that doesn't define one in the OpenAPI/Swagger specification.
Solutions:
-
If the endpoint should NOT accept a body (e.g., GET, DELETE requests): Remove the
withRequestBody()call from your test:// WRONG - GET requests typically don't have bodies $request->withMethod('GET') ->withPath('/pet/1') ->withRequestBody(['data' => 'value']); // ← Remove this // CORRECT $request->withMethod('GET') ->withPath('/pet/1');
-
If the endpoint SHOULD accept a body (e.g., POST, PUT, PATCH): Add the request body definition to your OpenAPI specification:
For OpenAPI 3.0:
paths: /pet: post: requestBody: # ← Add this required: true content: application/json: schema: $ref: '#/components/schemas/Pet'
For Swagger 2.0:
paths: /pet: post: parameters: - in: body # ← Add this parameter name: body required: true schema: $ref: '#/definitions/Pet'
Cause: No OpenAPI/Swagger schema has been configured for the test case.
Solution:
Add schema configuration in your test's setUp() method:
class MyTestCase extends \ByJG\ApiTools\ApiTestCase
{
public function setUp(): void
{
$schema = \ByJG\ApiTools\Base\Schema::fromFile('/path/to/openapi.json');
$this->setSchema($schema);
}
// Your tests...
}Alternative Solution: Configure schema per-request:
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withSchema($schema) // ← Set schema on request
->withMethod('GET')
->withPath('/pet/1');
$this->sendRequest($request);Cause: The OpenAPI specification marks the request body as required, but your test isn't providing one.
Solution: Add a request body to your test:
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('POST')
->withPath('/pet')
->withRequestBody([ // ← Add this
'name' => 'Fluffy',
'status' => 'available'
]);
$this->sendRequest($request);Cause: The path you're testing doesn't exist in your OpenAPI/Swagger specification.
Common Issues:
-
Path parameter mismatch:
// Your spec has: /pet/{petId} // But you're testing: /pet/1 // This should work - parameters are replaced automatically $request->withPath('/pet/1'); // ✓ Matches /pet/{petId}
-
Missing leading slash:
$request->withPath('pet/1'); // ✗ WRONG $request->withPath('/pet/1'); // ✓ CORRECT
-
Base path confusion: If your spec defines a base path (Swagger 2.0) or server URL (OpenAPI 3.0), don't include it in your test path:
# OpenAPI 3.0 servers: - url: https://api.example.com/v1 paths: /pet/{petId}: # ← Use this in your test
$request->withPath('/pet/1'); // ✓ CORRECT $request->withPath('/v1/pet/1'); // ✗ WRONG
-
Path doesn't exist in spec: Add the path to your OpenAPI specification:
paths: /pet/{petId}: # ← Add this path get: # ... operation definition
Cause: The HTTP method you're testing doesn't exist for that path in your specification.
Solution: Either:
-
Fix your test to use the correct HTTP method:
$request->withMethod('POST'); // Change to match your spec
-
Add the method to your OpenAPI specification:
paths: /pet/{petId}: get: # ← Already exists # ... put: # ← Add this method # ... operation definition
Cause: The API returned a different status code than expected.
Solution:
-
Adjust your expectation if the new status code is correct:
$request ->withMethod('POST') ->withPath('/pet') ->expectStatus(201); // ← Adjust this
-
Fix your API if it's returning the wrong status code.
-
Add the status code to your OpenAPI specification:
paths: /pet: post: responses: '201': # ← Add this response description: Pet created content: application/json: schema: $ref: '#/components/schemas/Pet'
Cause: A value doesn't match the regex pattern defined in your OpenAPI specification.
Example Spec:
schema:
type: string
pattern: '^[a-z]+$' # Only lowercase lettersSolution:
-
Fix your test data to match the pattern:
$request->withRequestBody([ 'status' => 'AVAILABLE' // ✗ WRONG - uppercase ]); $request->withRequestBody([ 'status' => 'available' // ✓ CORRECT - lowercase ]);
-
Fix the pattern in your spec if it's too restrictive:
pattern: '^[a-zA-Z]+$' # Allow both upper and lowercase
Cause: Your request/response is missing a required field defined in the specification.
Solution:
-
Add the missing field to your test:
$request->withRequestBody([ 'name' => 'Fluffy', 'status' => 'available', // ← Don't forget required fields ]);
-
Make the field optional in your spec if it shouldn't be required:
schema: type: object required: - name # Remove 'status' from required if optional properties: name: type: string status: type: string
Cause:
You're sending fields that aren't defined in your OpenAPI schema, and additionalProperties
is set to false (or not set, as false is the default).
Solution:
-
Remove extra fields from your test:
$request->withRequestBody([ 'name' => 'Fluffy', 'extraField' => 'value', // ← Remove this if not in spec ]);
-
Add the field to your OpenAPI specification:
schema: type: object properties: name: type: string extraField: # ← Add this type: string
-
Allow additional properties in your spec (not recommended for strict validation):
schema: type: object additionalProperties: true # ← Allow any extra properties properties: name: type: string
Ensure PHPUnit is configured to show detailed errors in your phpunit.xml.dist:
<phpunit
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
/>Capture the response to see what your API actually returned:
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1');
$response = $this->sendRequest($request);
// Debug: print the response
echo "Status: " . $response->getStatusCode() . "\n";
echo "Body: " . (string)$response->getBody() . "\n";
echo "Headers: " . print_r($response->getHeaders(), true) . "\n";Use online validators to ensure your specification is valid:
This library requires OpenAPI specifications in JSON format, not YAML.
Convert YAML to JSON:
# Using yq (https://github.com/mikefarah/yq)
yq eval -o=json openapi.yaml > openapi.json
# Using python
python -c 'import sys, yaml, json; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)' < openapi.yaml > openapi.jsonUse MockRequester to test your specification without making actual HTTP calls:
use ByJG\ApiTools\MockRequester;
use ByJG\WebRequest\Psr7\Response;
$expectedResponse = Response::getInstance(200)
->withBody(json_encode(['id' => 1, 'name' => 'Fluffy']));
$request = new MockRequester($expectedResponse);
$request
->withMethod('GET')
->withPath('/pet/1');
// This validates against the spec without HTTP
$this->sendRequest($request);If you're still stuck:
- Check the examples in the
/testsdirectory of this repository - Review the documentation:
- Search existing issues on GitHub Issues
- Ask for help by opening a new issue with:
- Your OpenAPI specification (or relevant portion)
- Your test code
- The full error message
- PHP and library versions
// Test success case
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->expectStatus(200);
$this->sendRequest($request);
// Test not found case
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/99999')
->expectStatus(404);
$this->sendRequest($request);$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->withRequestHeader([
'Authorization' => 'Bearer ' . $this->getAuthToken()
]);
$this->sendRequest($request);$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('POST')
->withPath('/pet/1/uploadImage')
->withRequestBody([
'file' => base64_encode(file_get_contents('/path/to/image.jpg')),
'filename' => 'image.jpg'
]);
$this->sendRequest($request);