I was learning how to do test drive development (tdd) as well as clean code architecture on flutter and I kept getting into unfamiliar problem again and again. That is – type ‘Null’ is not a subtype of type ‘Future<Either<Failure, NumberTrivia>>’. This method is declared in an abstract class NumberTriviaRepository
The NumberTrivia is a simple entity class as follow
class NumberTrivia extends Equatable {
final int number;
final String text;
const NumberTrivia({
required this.number,
required this.text,
});
@override
// TODO: implement props
List<Object?> get props => [number, text];
}
The NumberTriviaRepository
abstract class NumberTriviaRepository {
Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(int number);
Future<Either<Failure, NumberTrivia>> getRandomNumberTrivia();
}
The usecase – GetConcreteNumberTrivia
class GetConcreteNumberTrivia {
final NumberTriviaRepository repository;
GetConcreteNumberTrivia(this.repository);
Future<Either<Failure, NumberTrivia>> execute({required number}) async {
return await repository.getConcreteNumberTrivia(number);
}
}
Here is the main test file
class MockNumberTriviaRepository extends Mock
implements NumberTriviaRepository {}
void main() {
late MockNumberTriviaRepository mockNumberTriviaRepository;
late GetConcreteNumberTrivia usecase;
setUp(() {
mockNumberTriviaRepository = MockNumberTriviaRepository();
usecase = GetConcreteNumberTrivia(mockNumberTriviaRepository);
});
final testNumber = 1;
const testNumberTrivia = NumberTrivia(number: 1, text: 'test');
test('should get trivia for the number from the repository', () async {
when(mockNumberTriviaRepository.getConcreteNumberTrivia(testNumber))
.thenAnswer((_) async => const Right(testNumberTrivia));
final result = await usecase.execute(number: testNumber);
log('Result equals ${result}');
expect(result, equals(const Right(testNumberTrivia)));
verify(mockNumberTriviaRepository.getConcreteNumberTrivia(testNumber));
verifyNoMoreInteractions(mockNumberTriviaRepository);
});
}
I don’t know where I’m making a mistake but I’m having trouble passing this test case. I believe both the results should be NumberTrivia object but it seems like one of them is null and I can’t figure why that is the case.
I expect the object to be of the same type (NumberTrivia) in the expect function during the test
2
Answers
This might be caused if you are using an old Mockito version that does not support null-safety. Try upgrading your version to ^5.0.0.
This is frequently a pain if tutorials are from pre-null-safety or if some packages have significantly changed since then. Not sure if it was this or some bloc tutorial, one was causing me real headaches because it required significant changes to run in today’s version.
If you use version to ^5.0.0.
To use Mockito’s generated mock classes, add a build_runner dependency in your package’s pubspec.yaml file, under dev_dependencies; something like build_runner: ^1.11.0.
The resulting class is as follows, and you will pass the test
Example