How to write and run tests in Dart

Set up and write unit tests using Dart's built-in test package

Add the test package

dart pub add --dev test

Write a test

Create a file in test/ ending with _test.dart:

// test/calc_test.dart
import 'package:test/test.dart';
import '../lib/calc.dart';

void main() {
  test('addition works', () {
    expect(add(2, 3), equals(5));
  });

  test('strings are equal', () {
    expect('hello', equals('hello'));
  });
}

Run tests

# Run all tests
dart test

# Run a specific file
dart test test/calc_test.dart

# Run with verbose output
dart test -r expanded

# Run with coverage
dart test --coverage=coverage

Group tests

void main() {
  group('Calculator', () {
    test('adds two numbers', () {
      expect(add(2, 3), equals(5));
    });

    test('handles negative numbers', () {
      expect(add(-1, 1), equals(0));
    });

    test('handles zero', () {
      expect(add(0, 0), equals(0));
    });
  });
}

Setup and teardown

void main() {
  late Database db;

  setUp(() {
    db = Database(inMemory: true);
  });

  tearDown(() {
    db.close();
  });

  test('insert and find', () {
    db.insert('key', 'value');
    expect(db.find('key'), equals('value'));
  });
}

Matchers

test('matchers', () {
  expect(42, equals(42));
  expect(42, greaterThan(0));
  expect(42, lessThanOrEqualTo(100));
  expect([1, 2, 3], contains(2));
  expect([1, 2, 3], orderedEquals([1, 2, 3]));
  expect({'a': 1}, containsPair('a', 1));
  expect('hello', startsWith('h'));
  expect('hello', endsWith('o'));
  expect('hello', matches(RegExp(r'hell.')));
  expect(42, isNotNull);
  expect(null, isNull);
  expect(true, isTrue);
  expect(false, isFalse);
  expect(() => throw Exception(), throwsException);
  expect(() => int.parse('x'), throwsFormatException);
});

Asynchronous tests

test('async operation', () async {
  var result = await fetchData();
  expect(result, equals('data'));
});

test('stream', () async {
  var stream = countDown(3);
  expect(stream, emitsInOrder([3, 2, 1, 0]));
});

Mocking with mockito

dart pub add --dev mockito build_runner
// test/user_service_test.dart
import 'package:test/test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../lib/user_service.dart';

@GenerateNiceMocks([MockSpec<UserRepository>()])
import 'user_service_test.mocks.dart';

void main() {
  late MockUserRepository mockRepo;
  late UserService service;

  setUp(() {
    mockRepo = MockUserRepository();
    service = UserService(mockRepo);
  });

  test('getUserName returns name from repository', () async {
    when(mockRepo.findById(1)).thenAnswer((_) async => User(id: 1, name: 'Ada'));

    var name = await service.getUserName(1);
    expect(name, equals('Ada'));
    verify(mockRepo.findById(1)).called(1);
  });
}

Generate mocks:

dart run build_runner build