Flutter Unit Test Fails on Subclass

Issue

Method tested:

@override
  Future<Either<Failure, SampleModel>> getSampleModel(String activityType) async {
    if (await networkInfo.isConnected()) {
      final remoteModel = await remoteDataSource.getSampleModel(activityType);
      localDataSource.cacheSampleModel(remoteModel);
      return Right(remoteModel);
    } else {
      try {
        final localModel = await localDataSource.getSampleModel(activityType);
        return Right(localModel);
      } on CacheException {
        return Left(CacheFailure());
      }
    }
  }

Trying to test the failure scenario on the localDataSource.

The class structure for the failures looks like this:

abstract class Failure {
  Exception? exception;

  Failure() : exception = null;
}

class CacheFailure extends Failure {}

Simple enough, I think. And here is my test:

test(
      'should return failure when the call to remote data source is unsuccessful',
      () async {
    // arrange
    when(mockNetworkInfo.isConnected()).thenAnswer((_) async => false);
    when(mockLocalDataSource.getSampleModel(any)).thenThrow(CacheException());
    // act
    final result = await repository.getSampleModel(activityType);
    // assert
    verifyZeroInteractions(mockRemoteDataSource);
    verify(mockLocalDataSource.getSampleModel(activityType));
    expect(result, Left(CacheFailure()));
  });

The last line fails with this error:

Expected: Left<CacheFailure, dynamic>:<Left(Instance of
‘CacheFailure’)>
Actual: Left<Failure, SampleModel>:<Left(Instance
of ‘CacheFailure’)>

I’m confused since the method clearly returns a CacheFailure but the test suggests that I am returning the super class Failure. Further, why does this matter? A CacheFailure is a Failure.

Probably a simple oversight, but I just can’t see it.

Solution

That expect simply compares result == Left(CacheFailure()) in my thought.

How about using isA<Left<Failure, SampleModel>>() matcher?

Answered By – jeiea

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *