๐งช Swagger Fixtures
Test fixtures straight from your API's Swagger / OpenAPI spec.
swagger_fixtures reads the spec, writes one JSON file per documented response
โ built from the spec's own example values โ and generates a Dart file that
names every one of them, ready to parse in a test:
final user = Fixtures.getV1Users200.parse(User.fromJson);
When the backend changes a response, regenerate, and the tests that parse it tell you whether your models still fit.
๐ Features
- ๐ Reads one or many specs โ by URL or local path
- ๐ One JSON file per documented response, every status code included
- ๐งฉ Bodies built from the spec's
examplevalues,$refs followed - ๐ฏ A generated
Fixturesclass with a typed handle per response - ๐ Rerun to refresh; responses gone from the spec are cleaned up
๐ Installation
In a project (as dev dependency)
dart pub add -d swagger_fixtures
Or manually in pubspec.yaml:
dev_dependencies:
swagger_fixtures: ^0.2.0
Globally
dart pub global activate swagger_fixtures
Then run as swagger_fixtures from the package root.
โ๏ธ Configuration
Add a swagger_fixtures: section to the same pubspec.yaml:
swagger_fixtures:
# Required. One spec, or a list of them, JSON or YAML. A local file path works too.
swagger_url:
- https://api.example.com/auth/swagger/doc.json
- https://api.example.com/billing/swagger/doc.json
# Optional. Where the JSON files go. Default: test/fixtures
json_output_dir: test/fixtures
# Optional. Where the Dart file goes. Default: <json_output_dir>/fixtures.g.dart
dart_output_file: test/fixtures/fixtures.g.dart
Paths are relative to the package root.
๐ Usage
dart run swagger_fixtures
swagger_fixtures: 42 fixtures โ test/fixtures, test/fixtures/fixtures.g.dart
Rerun it whenever the spec changes. JSON files for responses that left the
spec are removed; other files in json_output_dir are left alone.
๐ What you get
For GET /v1/users/{userID} answering 200:
-
test/fixtures/get_v1_users_user_id_200.json -
in
fixtures.g.dart:abstract final class Fixtures { static const getV1UsersUserId200 = Fixture('test/fixtures/get_v1_users_user_id_200.json'); }
Names are <method><path words><status>, so every documented status code โ
401, 404, 422, โฆ โ gets its own fixture as well.
๐งช Use in tests
import 'package:test/test.dart'; // or flutter_test
import 'fixtures/fixtures.g.dart';
void main() {
test('user parses', () {
final user = Fixtures.getV1UsersUserId200.parse(User.fromJson);
expect(user.name, 'Ann');
});
}
Fixture reads its file on demand:
| Member | Returns |
|---|---|
raw |
the file as a String |
json |
jsonDecode(raw) |
map |
the body as Map<String, dynamic> |
list |
the body as List<dynamic> |
parse(fromJson) |
fromJson(map) |
Paths are relative to the package root, which is the working directory of both
dart test and flutter test.
๐จ How a body is built
For each response, the first of these that exists wins:
- the response's own example โ Swagger 2.0
examples['application/json'], OpenAPI 3content['application/json'].exampleor the first ofexamples; - a body built from the response schema:
- a schema's
example, thendefault, then the firstenumvalue; - objects are built property by property, arrays hold one item;
$ref,allOf(merged),oneOf/anyOf(first option) are followed;- anything else gets a placeholder of its type:
"string",0,0.0,false;date-time,date,uuidandemailstrings get a value in that format; - a type that contains itself stops at
nullon the repeat.
- a schema's
Responses without a JSON body (204, files) are skipped.
The more example values your spec carries, the closer the fixtures are to
real responses.
โ ๏ธ Limitations
- Local
$refs only (#/...). - Fixtures are read with
dart:io, so they work in VM tests (dart test,flutter test), not in browser tests.
Libraries
- swagger_fixtures
- Test fixtures from a Swagger / OpenAPI spec.