Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

dart-generate-test-mocks — Claude Code skill: mocks for Dart tests

A Dart testing skill: the agent injects external services through constructors, generates mock classes with mockito and build_runner, then writes the unit test.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add dart-lang/skills --skill dart-generate-test-mocks -a claude-code
Open on GitHub

What dart-generate-test-mocks does

This skill walks the agent through mocked unit tests in Dart. First the class under test gets reshaped for substitution: http.Client and similar services go in through the constructor, URLs travel as Uri objects. Test and codegen packages come from dart pub add dev:test dev:mockito dev:build_runner.

Then a test file gets @GenerateNiceMocks([MockSpec<http.Client>()]), imports the generated .mocks.dart, and dart run build_runner build writes the mock classes. For anything returning a Future or Stream the skill insists on thenAnswer rather than thenReturn. It also skips @GenerateMocks in favour of nice mocks, since an unstubbed method would otherwise throw.

A ten-step checklist runs alongside a failure loop: an ArgumentError from an async stub, an import name that does not match the .mocks.dart file, build errors. You need the Dart SDK and the pub packages — skip build_runner and the mock classes never appear, so the test will not compile.

What it helps with

  • Mock http.Client inside a service unit test
  • Generate mock classes with build_runner
  • Stub a method that returns a Future
  • Check that a mock method ran exactly once
  • Track down an ArgumentError from an async stub

Example prompts for the agent

  • Generate mocks for `ApiService` with `@GenerateNiceMocks` and run `dart run build_runner build`
  • Write a unit test for `fetchData`: mock `http.Client` and verify the call
  • The test throws `ArgumentError` — rewrite that async stub with `thenAnswer`

How to install dart-generate-test-mocks

1Skills CLI (Vercel)

npx skills add dart-lang/skills --skill dart-generate-test-mocks -a claude-code

2Manually: put the files in place

~/.claude/skills/dart-generate-test-mocks/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/dart-generate-test-mocks/

From the same set7

The whole set →

Similar

write-e2e-tests tldraw Guides Playwright E2E testing for tldraw, including UI actions, menus, and canvas shapes. Use it when adding coverage for SDK examples or the tldraw.com client. Claude Code CX Codex Cursor +1 430installs phoenix-evals official [email protected] Build and run evaluators for AI and LLM applications with Phoenix. Use it to investigate failures, evaluate RAG systems, and check model output. GitHub Copilot 1,000installs phoenix-cli official arize-ai A GitHub Copilot skill that drives the Phoenix CLI to pull traces, spans and sessions, then turns what it finds into a failure taxonomy for your LLM app. GitHub Copilot 1,000installs quantized-export Seth Hobson Exports promoted checkpoints and LoRA adapters as FP8, AWQ, GGUF, or merged safetensors. Use it before deploying a model. Claude Code CX Codex Cursor 2,600installs eval-harness-first Seth Hobson Builds the evaluation harness before fine-tuning with goldens, graders, judge calibration, and a base-model baseline. Useful for tracking regressions. Claude Code CX Codex Cursor 2,600installs checkpoint-promotion Seth Hobson Gates a trained checkpoint before release by checking data quality, capability drift, forgetting, and paired results against the base model. Claude Code CX Codex Cursor 2,600installs improve-codebase-architecture Matt Pocock This skill scans a codebase for architectural friction, then builds a visual HTML report with refactoring candidates. Use it before a deeper architecture review. Claude Code 1,163,035installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs

Questions about dart-generate-test-mocks

How do I install dart-generate-test-mocks in Claude Code?

Run npx skills add dart-lang/skills --skill dart-generate-test-mocks -a claude-code. The skill lands at ~/.claude/skills/dart-generate-test-mocks/SKILL.md.

What does dart-generate-test-mocks do?

It guides the agent from dependency injection in the class to package setup, mock generation and a finished test with stubs and call verification.

Why nice mocks instead of `@GenerateMocks`?

Nice mocks hand back empty values when a method has no stub, so the test fails on your assertion rather than on a missing-stub exception.

Source text

SKILL.md · BSD-3-Clause
---
name: dart-generate-test-mocks
description: Define and generate mock objects for external dependencies using `package:mockito` and `build_runner`. Use when unit testing classes that depend on complex external services like APIs or databases.
metadata:
  model: models/gemini-3.1-pro-preview
  last_modified: Fri, 24 Apr 2026 15:13:58 GMT
---
# Testing and Mocking Dart Applications

## Contents
- [Structuring Code for Testability](#structuring-code-for-testability)
- [Managing Dependencies](#managing-dependencies)
- [Generating Mocks](#generating-mocks)
- [Implementing Unit Tests](#implementing-unit-tests)
- [Workflow: Creating and Running Mocked Tests](#workflow-creating-and-running-mocked-tests)
- [Examples](#examples)

## Structuring Code for Testability
Design Dart classes to support dependency injection. Isolate complex external dependencies (like API clients or databases) so they can be replaced with mock objects during testing.

- Inject external services (e.g., `http.Client`) through class constructors.
- Represent URLs strictly as `Uri` objects using `Uri.parse(string)`.
- Utilize Dart's object-oriented features (classes, mixins) to define clear interfaces for external interactions.

## Managing Dependencies
Configure the `pubspec.yaml` file with the necessary testing and code generation packages.

- Add runtime dependencies (e.g., `package:http`) using `dart pub add http`.
- Add testing dependencies using `dart pub add dev:test dev:mockito dev:build_runner`.
- Import HTTP libraries with a prefix to avoid namespace collisions: `import 'package:http/http.dart' as http;`.

## Generating Mocks
Use `package:mockito` and `build_runner` to automatically generate mock classes for fixed scenarios and behavior verification.

- Always use the `@GenerateNiceMocks` annotation (preferable to `@GenerateMocks` to avoid missing stub exceptions).
- Place the annotation in the test file, passing a list of `MockSpec<Type>()` objects.
- Import the generated file using the `.mocks.dart` extension.
- Execute `build_runner` to generate the mock files: `dart run build_runner build`.

## Implementing Unit Tests
Isolate the system under test using the generated mock objects. Use `package:test` to structure the test suite.

- **Stubbing:** Configure mock behavior before interacting with the system under test.
  - Use `when(mock.method()).thenReturn(value)` for synchronous methods.
  - **CRITICAL:** Always use `thenAnswer((_) async => value)` for methods returning a `Future` or `Stream`. Never use `thenReturn` for asynchronous returns.
- **Verification:** Assert that the system under test interacted with the mock object correctly.
  - Use `verify(mock.method()).called(1)` to check exact invocation counts.
  - Use argument matchers like `any`, `anyNamed`, or `captureAny` for flexible verification.

## Workflow: Creating and Running Mocked Tests

Use the following checklist to implement and verify mocked unit tests.

### Task Progress
- [ ] 1. Identify the external dependency to mock (e.g., `http.Client`).
- [ ] 2. Inject the dependency into the target class constructor.
- [ ] 3. Create a test file (e.g., `target_test.dart`) and add `@GenerateNiceMocks([MockSpec<Dependency>()])`.
- [ ] 4. Add the `part` or `import` directive for the generated `.mocks.dart` file.
- [ ] 5. Run `dart run build_runner build` to generate the mock classes.
- [ ] 6. Write the test cases using `group()` and `test()`.
- [ ] 7. Stub required behaviors using `when()`.
- [ ] 8. Execute the target method.
- [ ] 9. Verify interactions using `verify()` and assert outcomes using `expect()`.
- [ ] 10. Run the test suite using `dart test`.

### Feedback Loop: Test Failures
If tests fail or `build_runner` encounters errors:
1. **Run validator:** Execute `dart test` or `dart run build_runner build`.
2. **Review errors:** Check for missing stubs, mismatched argument matchers, or syntax errors in the generated files.
3. **Fix:**
   - If a mock method throws an unexpected null error, ensure you used `@GenerateNiceMocks`.
   - If an async stub throws an `ArgumentError`, change `thenReturn` to `thenAnswer`.
   - If `build_runner` fails, ensure the `.mocks.dart` import matches the file name exactly.
4. Repeat until all tests pass.

## Examples

### High-Fidelity Mocking and Testing Example

**1. System Under Test (`lib/api_service.dart`)**
```dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class ApiService {
  final http.Client client;

  ApiService(this.client);

  Future<String> fetchData(String urlString) async {
    final uri = Uri.parse(urlString);
    final response = await client.get(uri);

    if (response.statusCode == 200) {
      return jsonDecode(response.body)['data'];
    } else {
      throw Exception('Failed to load data');
    }
  }
}
```

**2. Test Implementation (`test/api_service_test.dart`)**
```dart
import 'package:test/test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:http/http.dart' as http;
import 'package:my_app/api_service.dart';

// Generate the mock class for http.Client
@GenerateNiceMocks([MockSpec<http.Client>()])
import 'api_service_test.mocks.dart';

void main() {
  group('ApiService', () {
    late ApiService apiService;
    late MockClient mockHttpClient;

    setUp(() {
      mockHttpClient = MockClient();
      apiService = ApiService(mockHttpClient);
    });

    test('returns data if the http call completes successfully', () async {
      // Arrange: Stub the async HTTP GET request using thenAnswer
      when(mockHttpClient.get(any)).thenAnswer(
        (_) async => http.Response('{"data": "Success"}', 200),
      );

      // Act
      final result = await apiService.fetchData('https://api.example.com/data');

      // Assert
      expect(result, 'Success');

      // Verify the mock was called with the correct Uri
      verify(mockHttpClient.get(Uri.parse('https://api.example.com/data'))).called(1);
    });

    test('throws an exception if the http call completes with an error', () {
      // Arrange
      when(mockHttpClient.get(any)).thenAnswer(
        (_) async => http.Response('Not Found', 404),
      );

      // Act & Assert
      expect(
        apiService.fetchData('https://api.example.com/data'),
        throwsException,
      );
    });
  });
}
```

© dart-lang · BSD-3-Clause · dart-lang/skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor