Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write tests for Either<> from dartz package in flutter

I am trying to write unit tests for a flutter app and I can't get this one test case to work correctly.

Here is the function returning Future<Either<WeatherData, DataError>>:

@override 
Future<Either<WeatherData, DataError>> fetchWeatherByCity({required String city}) async {
    try {
      var response = await apiService.fetchWeatherByCity(city: city);
      if (response.statusCode == 200) {
        return Left(WeatherData.fromJson(jsonDecode(response.body)));
      } else {
        return Right(DataError(title: "Error", description: "Desc", code: 0, url: "NoUrl"));
      }
    } catch (error) {
      AppException exception = error as AppException;
      return Right(DataError(
          title: exception.title, description: exception.description, code: exception.code, url: exception.url));
    }
}


Here is the code where I am trying to write the unit test:

sut = WeatherRepositoryImpl(apiService: mockWeatherApiService);
test(
  "get weather by city DataError 1 - Error 404 ",
  () async {
    when(mockWeatherApiService.fetchWeatherByCity(city: "city"))
        .thenAnswer((_) async => Future.value(weatherRepoMockData.badResponse));
    final result = await sut.fetchWeatherByCity(city: "city");
    verify(mockWeatherApiService.fetchWeatherByCity(city: "city")).called(1);
    expect(result, isInstanceOf<DataError>);
        verifyNoMoreInteractions(mockWeatherApiService);
  },
);

When I run this specific test, I receive this error:

    Expected: <Instance of 'DataError'>
    Actual: Right<WeatherData, DataError>:<Right(Instance of 'DataError')>
    Which: is not an instance of 'DataError'

What I am not getting here? What should I be expecting from the function for the test to pass successfully?

like image 911
Ashish Avatar asked Oct 19 '25 03:10

Ashish


2 Answers

You are directly using the result which is actually a wrapper and has a type of Either<WeatherData, DataError>.

You need to unwrap the value using the fold method on the result and then expect accordingly, So in your code you can do something like this to make it work:

final result = await sut.fetchWeatherByCity(city: "city");

result.fold(
(left) => fail('test failed'), 
(right) {
  expect(result, isInstanceOf<DataError>);
});
verifyNoMoreInteractions(mockWeatherApiService);

Hope this helps.

like image 92
Hitesh Garg Avatar answered Oct 20 '25 20:10

Hitesh Garg


You need to either make the expected value a Right(), or extract the right side of the actual value. Doing either of those will match, but as it is, you're comparing a wrapped value with an unwrapped value.

like image 26
Randal Schwartz Avatar answered Oct 20 '25 18:10

Randal Schwartz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!