Skip to main content

bloc_signals_test 1.0.3 copy "bloc_signals_test: ^1.0.3" to clipboard
bloc_signals_test: ^1.0.3 copied to clipboard

Declarative unit testing utilities for BlocSignal and CubitSignal.

bloc_signals_test

โšก bloc_signals_test

"With the rigor of BLoC and the flex and speed of Signals"

Declarative unit testing utilities for bloc_signals and CubitSignal instances.

bloc_signals_test provides blocSignalTest, a declarative helper tailored specifically for synchronous reactive signal state propagation, state de-duplication, and observer isolation.


๐ŸŒ Ecosystem Packages #

The BlocSignal monorepo consists of 11 modular packages:

Package Version Description
bloc_signals pub Core pure Dart reactive state primitives bridging BLoC & Signals
bloc_signals_flutter pub Flutter UI bindings, providers, builders, listeners & selectors
bloc_signals_bloc pub Classic BLoC 8/9 interop adapters & bidirectional event bridges
bloc_signals_riverpod pub Bidirectional Riverpod 2/3 interop adapters & provider extensions
bloc_signals_jaspr pub Jaspr web component integration and state binding for BlocSignal
bloc_signals_hydrate pub Automated synchronous local state persistence & hydration
bloc_signals_replay pub Undo & redo state history tracking for CubitSignal and BlocSignal
bloc_signals_otel pub OpenTelemetry tracing and span generation for state transitions
bloc_signals_devtools pub Universal DevTools telemetry observer using dart:developer
bloc_signals_test pub Declarative unit testing utilities (blocSignalTest)
bloc_signals_lint pub Custom analyzer lint rules & automated IDE quick-fixes

โšก Key Features #

  • ๐ŸŽฏ Declarative Assertions: Verify emitted states in exact order using expect.
  • โฑ๏ธ Async Support: Await asynchronous event handlers or timers using wait.
  • โญ๏ธ State Skipping: Skip initial emissions using skip.
  • ๐Ÿšจ Error Testing: Verify exceptions reported to onError, rethrown Error subtypes (for example StateError or ArgumentError), and direct CubitSignal method throws using errors.
  • ๐Ÿงน Automatic Cleanup: Guarantees observer restoration and bloc.close() post-test.

๐Ÿš€ Getting Started #

Add bloc_signals_test to your pubspec.yaml:

dev_dependencies:
  bloc_signals_test: ^1.0.0
  test: ^1.24.0

๐Ÿ’ก Quick Examples #

1. Cubit Unit Test (blocSignalTest) #

import 'package:bloc_signals_test/bloc_signals_test.dart';
import 'package:test/test.dart';

void main() {
  group('CounterCubit', () {
    blocSignalTest<CounterCubit, int>(
      'emits [1] when increment is called',
      build: CounterCubit.new,
      act: (cubit) => cubit.increment(),
      expect: () => [1],
    );
  });
}

2. Async Event Bloc Test (wait & errors) #

blocSignalTest<DataBloc, DataState>(
  'emits [DataLoading, DataLoaded] when FetchData succeeds',
  build: () => DataBloc(repository: mockRepo),
  act: (bloc) => bloc.add(FetchData()),
  wait: const Duration(milliseconds: 100),
  expect: () => [
    const DataLoading(),
    const DataLoaded('sample_data'),
  ],
);

3. Mocking & Faking for Widget & Golden Tests #

In BlocSignal, cubit.state is a reactive ReadonlySignal<S> (which BlocSignalBuilder, BlocSignalListener, BlocSignalSelector, and context.select subscribe to inside reactive effects and computeds), while cubit.value (and cubit.stateValue) returns the raw S snapshot. Attempting to stub when(() => cubit.state).thenReturn(MyLoadedState()) with mocktail will fail because MyLoadedState is not a ReadonlySignal<MyState>.

Because CubitSignal and BlocSignal are streamless and propagate state synchronously in the same frame, the cleanest pattern for widget and golden tests is either seeding a real container via initialState: or creating a lightweight Fake class:

class FakeUserCubit extends CubitSignal<UserState> implements UserCubit {
  FakeUserCubit({super.initialState = const UserInitial()});

  void emitState(UserState newState) => emit(newState);

  @override
  Future<void> refresh() async {}
}

// In testWidgets:
final fakeCubit = FakeUserCubit(initialState: const UserLoading());
addTearDown(fakeCubit.close);

await tester.pumpWidget(
  MaterialApp(
    home: BlocSignalProvider<UserCubit>.value(
      value: fakeCubit,
      child: const UserProfileView(),
    ),
  ),
);

fakeCubit.emitState(const UserLoaded('Alice'));
await tester.pump();

Stubbing with mocktail and a Backing signal<S>()

When you need mocktail verification (for example, verify(() => mockCubit.refresh()).called(1)), back mockCubit.state with a real signal<S>(), register a fallback state value for equals(any(), any()), and dispose the backing signal in close() via addTearDown(mockCubit.close):

class MockUserCubit extends Mock implements UserCubit {}

// In main():
setUpAll(() => registerFallbackValue(const UserInitial()));

// In testWidgets:
final mockCubit = MockUserCubit();
final stateSignal = signal<UserState>(const UserInitial());
addTearDown(mockCubit.close);

when(() => mockCubit.state).thenReturn(stateSignal);
when(() => mockCubit.value).thenAnswer((_) => stateSignal.value);
when(() => mockCubit.stateValue).thenAnswer((_) => stateSignal.value);
when(() => mockCubit.equals(any(), any())).thenAnswer(
  (inv) => inv.positionalArguments[0] == inv.positionalArguments[1],
);
when(() => mockCubit.isClosed).thenReturn(false);
when(() => mockCubit.close()).thenAnswer((_) async => stateSignal.dispose());

// Trigger reactive widget rebuilds by mutating stateSignal.value:
stateSignal.value = const UserLoaded('Alice');
await tester.pump();

๐Ÿค– AI Coding Assistant Skill #

This package is supported by an official pre-packaged AI Coding Skill representing unit testing patterns, observer isolation, and synchronous assertion guidelines for BlocSignal.

If you develop with AI coding assistants (such as Claude Code, Antigravity, Gemini, Cursor, or Codex), you can load the bloc-signals skill bundle to guide your assistant's code generation and analysis.


๐Ÿ“œ License #

MIT License. See LICENSE for details.

1
likes
160
points
1.02k
downloads

Documentation

API reference

Publisher

verified publisherblocsignal.dev

Weekly Downloads

Declarative unit testing utilities for BlocSignal and CubitSignal.

Repository (GitHub)
View/report issues
Contributing

Topics

#testing #unit-testing #bloc #signals

License

MIT (license)

Dependencies

bloc_signals, meta, test

More

Packages that depend on bloc_signals_test