Skip to content

Assertions

The reacton_test package provides assertion extensions on ReactonStore for clean, expressive test expectations. These are defined in the ReactonStoreTestExtensions extension.

Import

dart
import 'package:flutter_test/flutter_test.dart';
import 'package:reacton_test/reacton_test.dart';

API Reference

MethodDescription
expectReacton<T>(reacton, expected)Assert a reacton has a specific value
expectLoading<T>(reacton)Assert an async reacton is in loading state
expectData<T>(reacton, expected)Assert an async reacton has specific data
expectError<T>(reacton)Assert an async reacton is in error state
collectValues<T>(reacton, action)Collect all emitted values during an action
expectEmissions<T>(reacton, action, expected)Assert specific emissions during an action
expectEmissionCount<T>(reacton, action, count)Assert the number of emissions during an action

expectReacton

Assert that a reacton currently holds a specific value.

dart
void expectReacton<T>(ReactonBase<T> reacton, T expected)
dart
test('counter has expected value', () {
  final store = TestReactonStore();
  store.set(counterReacton, 42);

  store.expectReacton(counterReacton, 42);
});

When the assertion fails, it provides a clear error message:

Expected counter to be 42, but was 0

expectLoading

Assert that an async reacton is currently in the loading state.

dart
void expectLoading<T>(ReactonBase<AsyncValue<T>> reacton)
dart
test('weather starts as loading', () {
  final store = TestReactonStore(overrides: [
    AsyncReactonTestOverride.loading(weatherReacton),
  ]);

  store.expectLoading(weatherReacton);
});

expectData

Assert that an async reacton has completed with specific data.

dart
void expectData<T>(ReactonBase<AsyncValue<T>> reacton, T expected)
dart
test('weather has data', () {
  final store = TestReactonStore(overrides: [
    AsyncReactonTestOverride.data(weatherReacton, Weather(temp: 72)),
  ]);

  store.expectData(weatherReacton, Weather(temp: 72));
});

This asserts two things:

  1. The async value is in the data state (hasData is true)
  2. The contained value equals the expected value

expectError

Assert that an async reacton is in the error state.

dart
void expectError<T>(ReactonBase<AsyncValue<T>> reacton)
dart
test('weather has error', () {
  final store = TestReactonStore(overrides: [
    AsyncReactonTestOverride.error(
      weatherReacton,
      Exception('timeout'),
    ),
  ]);

  store.expectError(weatherReacton);
});

collectValues

Collect all values emitted by a reacton during a synchronous action block. Returns the list of emitted values.

dart
List<T> collectValues<T>(ReactonBase<T> reacton, void Function() action)
dart
test('collects emitted values', () {
  final store = TestReactonStore();

  final values = store.collectValues(counterReacton, () {
    store.set(counterReacton, 1);
    store.set(counterReacton, 2);
    store.set(counterReacton, 3);
  });

  expect(values, [1, 2, 3]);
});

TIP

collectValues subscribes before the action and unsubscribes after, so it only captures values emitted during the action block. The subscription is automatically cleaned up.

expectEmissions

Assert that a reacton emits exactly the expected values in order during an action block.

dart
void expectEmissions<T>(
  ReactonBase<T> reacton,
  void Function() action,
  List<T> expectedValues,
)
dart
test('counter emits correct sequence', () {
  final store = TestReactonStore();

  store.expectEmissions(
    counterReacton,
    () {
      store.set(counterReacton, 10);
      store.set(counterReacton, 20);
      store.set(counterReacton, 30);
    },
    [10, 20, 30],
  );
});

When the assertion fails:

Expected emissions [10, 20, 30], but got [10, 20]

expectEmissionCount

Assert that a reacton emits exactly N values during an action block.

dart
void expectEmissionCount<T>(
  ReactonBase<T> reacton,
  void Function() action,
  int expectedCount,
)
dart
test('batch emits once', () {
  final store = TestReactonStore();

  // Without batch: two emissions
  store.expectEmissionCount(
    counterReacton,
    () {
      store.set(counterReacton, 1);
      store.set(counterReacton, 2);
    },
    2,
  );
});

This is useful for verifying that batch operations or equality checks reduce unnecessary notifications.

Combining Assertions

These assertions compose well together for thorough tests:

dart
test('full computed reacton test', () {
  final store = TestReactonStore();

  // Verify initial state
  store.expectReacton(todosReacton, []);
  store.expectReacton(todoCountReacton, 0);

  // Verify emissions during mutation
  store.expectEmissions(
    todoCountReacton,
    () {
      store.set(todosReacton, ['A']);
      store.set(todosReacton, ['A', 'B']);
      store.set(todosReacton, ['A', 'B', 'C']);
    },
    [1, 2, 3],
  );

  // Verify final state
  store.expectReacton(todoCountReacton, 3);
});

Testing Equality Suppression

Reacton skips notifications when the new value equals the old value. Use expectEmissionCount to verify this behavior:

dart
test('skips duplicate values', () {
  final store = TestReactonStore();

  store.expectEmissionCount(
    counterReacton,
    () {
      store.set(counterReacton, 1);
      store.set(counterReacton, 1); // duplicate -- skipped
      store.set(counterReacton, 2);
    },
    2, // only 1 and 2, not the duplicate
  );
});

What's Next

Released under the MIT License.