mogen_unit_tests 1.0.21 copy "mogen_unit_tests: ^1.0.21" to clipboard
mogen_unit_tests: ^1.0.21 copied to clipboard

[pending analysis]

Scans Riverpod AsyncNotifier classes and auto-generates Mocktail unit tests.

mogen_unit_tests #

mogen_unit_tests scans your Flutter feature folders, parses Riverpod notifiers, and generates Mocktail-based unit test scaffolding for each discovered notifier.

It is designed for projects that keep their notifier and state files under lib/features/**/presentation/ and want a fast starting point for repeatable unit tests.


What it generates #

For every notifier it finds, the package creates a ready-to-run test file with:

  • Mock<Repository> classes for every repository dependency found via ref.read(...) or ref.watch(...)
  • Fake<Type> classes and registerFallbackValue(...) calls for complex parameter types
  • a ProviderContainer with repository overrides in setUp
  • container.dispose() in tearDown
  • one test group per public notifier method, each with a single successful execution case
  • optional state field assertions when stateInfo is available

Project layout #

The CLI expects this layout inside your Flutter app:

lib/
└── features/
    └── cart/
        └── presentation/
            ├── notifiers/
            │   └── cart_notifier.dart
            └── states/
                └── cart_state.dart

Installation #

Add the package to your Flutter app's dev_dependencies:

dev_dependencies:
    mogen_unit_tests:

Install it:

dart pub get

Usage #

Run the generator from the root of your Flutter app:

dart run mogen_unit_tests

CLI options #

Flag Short Default Description
--root -r . Project root directory
--dry-run -d false Preview generated files without writing them
--verbose -v false Print progress details while scanning and generating
--version Print the package version and exit
--help -h Show the CLI help text

Examples #

# Generate tests from the current directory
dart run mogen_unit_tests

# Preview the output without writing files
dart run mogen_unit_tests --dry-run --verbose

# Run against a different Flutter project
dart run mogen_unit_tests --root /path/to/my_flutter_app

Example #

Input notifier #

@riverpod
class CartNotifier extends _$CartNotifier {
  @override
  Future<CartState> build() async {
    final repo = ref.read(cartRepositoryProvider);
    return repo.fetchCart();
  }

  Future<void> addItem(CartItem item) async {
    final repo = ref.read(cartRepositoryProvider);
    await repo.addItem(item);
    ref.invalidateSelf();
  }

  Future<void> clearCart() async {
    final repo = ref.read(cartRepositoryProvider);
    await repo.clearCart();
    ref.invalidateSelf();
  }
}

Input state #

class CartState {
  final List<CartItem> items;
  final double total;

  const CartState({required this.items, required this.total});
}

Generated output #

Note: the generator creates test groups for public notifier methods only. build() is not scaffolded as its own test group.

// GENERATED BY mogen_unit_tests — DO NOT EDIT
// ignore_for_file: lines_longer_than_80_chars

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

import 'package:my_app/features/cart/presentation/notifiers/cart_notifier.dart';
import 'package:my_app/features/cart/presentation/states/cart_state.dart';
import 'package:my_app/features/cart/domain/repositories/cart_repository.dart';
import 'package:my_app/features/cart/data/repositories/cart_repository_impl.dart';

class MockCartRepository extends Mock implements CartRepository {}

class FakeCartItem extends Fake implements CartItem {}

void main() {
  group('CartNotifier', () {
    late MockCartRepository mockCartRepository;
    late ProviderContainer container;

    setUpAll(() {
      registerFallbackValue(FakeCartItem());
    });

    setUp(() {
      mockCartRepository = MockCartRepository();

      container = ProviderContainer(
        overrides: [
          cartRepositoryProvider.overrideWithValue(mockCartRepository),
        ],
      );
    });

    tearDown(() {
      container.dispose();
    });

    group('addItem', () {
      test('addItem completes successfully', () async {
        when(() => mockCartRepository.addItem(any()))
            .thenAnswer((_) async => null);

        final item = FakeCartItem();

        await container.read(cartNotifierProvider.future);
        await container.read(cartNotifierProvider.notifier).addItem(item);

        final finalState = container.read(cartNotifierProvider);

        expect(finalState.requireValue.error, isNull);
        expect(finalState.requireValue.isLoadingAction, isFalse);
      });
    });

    group('clearCart', () {
      test('clearCart completes successfully', () async {
        when(() => mockCartRepository.clearCart(any()))
            .thenAnswer((_) async => null);

        await container.read(cartNotifierProvider.future);
        await container.read(cartNotifierProvider.notifier).clearCart();

        final finalState = container.read(cartNotifierProvider);

        expect(finalState.requireValue.error, isNull);
        expect(finalState.requireValue.isLoadingAction, isFalse);
      });
    });
  });
}

What you still need to fill in #

The generator creates repository method stubs automatically. If a repository method returns a non-null value, update the generated thenAnswer(...) call to return a realistic object instead of null.

Everything else is generated for you.


Supported notifier types #

Class Supported
AsyncNotifier<T>
AutoDisposeAsyncNotifier<T>
Notifier<T>
AutoDisposeNotifier<T>

Repository dependencies are detected from ref.read(...) and ref.watch(...) calls inside the notifier implementation.


Limitations #

  • Generates unit tests only — no widget or integration tests
  • Repository stubs are autogenerated and may require manual return-value adjustments
  • Only notifiers under presentation/notifiers/ are scanned
  • family notifiers are not supported yet

Dependencies #

Package Purpose
analyzer AST parsing of notifier source files
dart_style Formatting generated Dart output
args CLI flag parsing
glob Discovering feature folders
path Cross-platform path handling
yaml Reading package name from pubspec.yaml

Project health notes #

  • This package is a CLI tool, not a Flutter app. Running dart run mogen_unit_tests from this repository itself will not produce output unless you point it at a consuming Flutter app with lib/features/....
  • The current output destination is test/unit/features/..., which is now reflected in the examples above.
1
likes
0
points
250
downloads

Publisher

unverified uploader

Weekly Downloads

Scans Riverpod AsyncNotifier classes and auto-generates Mocktail unit tests.

Homepage
Repository (GitHub)
View/report issues

License

(pending) (license)

Dependencies

analyzer, args, dart_style, glob, path, yaml

More

Packages that depend on mogen_unit_tests