Flutter Unit Class with Initializer

Viewed 43

I'm trying to write the unit test for this class, but I'm having problems about the initializer... When I instantiate the class in the test file, the caller throws an error that " Null check operator used on a null value". I know that's because the UserProvider is not initialized on the test folders. But how can I mock this??

class ContactController extends ChangeNotifier {
  BuildContext context;

  ContactController(this.context) {
    initializeData();
  }

  late Contact contact;

  initializeData() {
    var userProvider = context.read<UserProvider>();
    var currentContact = userProvider?.contact;

    if (currentContact != null) {
      newContact = currentContact;
    }

    notifyListeners();
  }
}
1 Answers

The code below should do the trick. The thing is that you need to provide a mocked UserProvider into the context. To do so, just use MultiProvider in the tests to inject the mocked one.

Note the use of @GenerateMocks([UserProvider]). This comes from mockito and it annotates the source to generate the MockUserProvider class. And to generate the *.mocks.dart just run flutter pub run build_runner build.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';

import 'package:so72756235_test_provider/contact_controller.dart';
import 'contact_controller_test.mocks.dart';

@GenerateMocks([UserProvider])
void main() {
  testWidgets('ContactController test', (WidgetTester tester) async {
    final mockUserProvider = MockUserProvider();
    when(mockUserProvider.contact).thenReturn(const Contact(name: 'Test'));

    await tester.pumpWidget(
      MultiProvider(
        providers: [
          Provider<UserProvider>(create: (_) => mockUserProvider),
          ChangeNotifierProvider(
              create: (context) => ContactController(context)),
        ],
        child: Consumer<ContactController>(
            builder: (context, value, child) =>
                Text(value.newContact.name, textDirection: TextDirection.ltr)),
      ),
    );

    expect(find.text('Test'), findsOneWidget);
  });
}
Related