Home > OS >  Flutter Unit Test Fails on Subclass
Flutter Unit Test Fails on Subclass

Time:03-01

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.

CodePudding user response:

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

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

  • Related