Sparround

Provider ilə yazılmış kodun testi

Provider ilə test iki səviyyəyə bölünür:

  • Unit testChangeNotifier adi Dart obyektidir, widget lazım deyil. Metodu çağırırsınız, addListener ilə bildirişlərin sayını, sonra state-i yoxlayırsınız. Bu testlər sürətlidir və UI-dan asılı deyil.
  • Widget test — widget-i ChangeNotifierProvider.value ilə əhatə edib fake model ötürürsünüz. .value seçimi burada vacibdir: modeli test özü yaradır və ömrünü özü idarə edir.

Üçüncü, tez-tez yaddan çıxan səviyyə — notifier-in dispose davranışı: söküldükdən sonra subscription-ların dayandığını yoxlayan test real sızmaların qarşısını alır.

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

void main() {
  test('add() elementi əlavə edir və bir dəfə bildiriş verir', () {
    final model = CartModel();
    var notifications = 0;
    model.addListener(() => notifications++);

    model.add(const Item(id: '1', price: 10));

    expect(model.items, hasLength(1));
    expect(notifications, 1); // lazımsız bildirişləri tutur
  });

  test('eyni elementi ikinci dəfə əlavə etmək bildiriş vermir', () {
    final model = CartModel()..add(const Item(id: '1', price: 10));
    var notifications = 0;
    model.addListener(() => notifications++);

    model.add(const Item(id: '1', price: 10));

    expect(notifications, 0);
  });
}

Notifier-in unit testi: bildirişlərin sayı da yoxlanılır.

dart
class FakeCartModel extends ChangeNotifier implements CartModel {
  @override
  List<Item> items = const [];

  @override
  double get totalPrice => items.fold(0, (sum, i) => sum + i.price);

  void setItems(List<Item> value) {
    items = value;
    notifyListeners();
  }

  @override
  void add(Item item) => setItems([...items, item]);
}

void main() {
  testWidgets('səbətin cəmi göstərilir və yenilənir', (tester) async {
    final fake = FakeCartModel();

    await tester.pumpWidget(
      ChangeNotifierProvider<CartModel>.value(
        value: fake,
        child: const MaterialApp(home: CartSummary()),
      ),
    );

    expect(find.text('Cəmi: 0.0'), findsOneWidget);

    fake.setItems([const Item(id: '1', price: 12.5)]);
    await tester.pump(); // bildirişdən sonra bir frame

    expect(find.text('Cəmi: 12.5'), findsOneWidget);
  });
}

Widget testi: fake model `.value` ilə ötürülür.

Widget testində ChangeNotifierProvider(create: ...) istifadə etsəniz, test bitəndə provider modeli sökür — bu, tester.pumpWidget ilə növbəti mərhələdə həmin obyektə müraciət etmək istəyəndə "used after disposed" xətasına apara bilər. Test daxilində modelin sahibi test özü olsun: .value və lazım olduqda addTearDown(fake.dispose).

Nə test olunurTest növüAlət
State məntiqi (hesablama, validasiya, error idarəsi)Unit`test()` + `addListener`
UI-ın state-ə reaksiyasıWidget`testWidgets()` + `ChangeNotifierProvider.value`
Repository ilə əlaqəUnit + fake/mock repositoryƏl ilə yazılmış fake ya mocking paketi
Sızma və disposeUnit`dispose()` sonrası davranışın yoxlanışı

📚 Mənbələr və sənədlər