Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

type 'Null' is not a subtype of type 'Future<List<Contact>>'

Olá pessoal,

Estou tentando executar o primeiro teste usando o Mockito, mas recebo uma mensagem de erro que parece resultado do mock retornar um valor 'Null'.

Esse é erro:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following _TypeError was thrown building ContactsList(dirty, state: _ContactsListState#ea57c):
type 'Null' is not a subtype of type 'Future<List<Contact>>'

The relevant error-causing widget was:
  ContactsList
  file:///home/fabio/Projetos/alura/flutter/bytebank_testes/lib/screens/dashboard.dart:61:31

When the exception was thrown, this was the stack:
#0      MockContactDao.findAll (package:bytebank_testes/database/dao/contact_dao.dart:28:25)
#1      _ContactsListState.build (package:bytebank_testes/screens/contacts_list.dart:26:35)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)

Essa é a linha 26 do contacts_list.dart:

      body: FutureBuilder<List<Contact>>(
        initialData: [],
        future: widget.contactDao.findAll(),  // Linha 26
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
              break;
            case ConnectionState.waiting:
              return Progress();
            case ConnectionState.active:
              break;

Essa é a linha 28 do contact_dao.dart:

  Future<List<Contact>> findAll() async {  // Linha 28
    final Database db = await getDatabase();
    final List<Map<String, dynamic>> result = await db.query(_tableName);
    List<Contact> contacts = _toList(result);
    return contacts;
  }

Essa é a linha 61 do dashboard.dart:

  void _showContactList(BuildContext context) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => ContactsList(contactDao: contactDao), // Linha 61
      ),
    );
  }
1 resposta
solução!

Resolvi o meu problema depois de ler a documentação do flutter com mais calma. O mockito 5.0.0 e superiores suportam null safety através de geração de código. Para executar a geração de código necessária, é preciso adicionar mais uma dependência no dev_dependencies chamada build_runner.

dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito:
  build_runner:

Daí criar o arquivo de teste com uma anotação especificando o mock e executar um comando no terminal: flutter pub run build_runner build

import 'package:mockito/annotations.dart';

@GenerateMocks([ContactDao])
void main() {
  testWidgets('Should save a contact', (tester) async {
  }
}

Esse comando vai gerar um arquivo de mock na mesma pasta do arquivo de teste que pode ser importado no arquivo de teste. Então, você pode definir o que o mock vai rentornar usando a função when(). Retornei uma lista vazia nesse caso.

import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'save_contact_flow.mocks.dart';

@GenerateMocks([ContactDao])
void main() {
  testWidgets('Should save a contact', (tester) async {
    final mockContactDao = MockContactDao();

    when(mockContactDao.findAll()).thenAnswer((_) async => []);
    await tester.pumpWidget(ByteBankApp(contactDao: mockContactDao));

    // Resto do teste //

  }    
}