jeudi 11 juin 2020

How can I test / mock Hive (Flutter) open box logic in repo?

Sorry if this seems a dumb question. I'm learning clean architecture as dictated by Rob Martin, and I've having a tiny bit of trouble writing one of my tests.

I wrote a couple functions in a Hive repo. Here's the code

import 'package:hive/hive.dart';
import 'package:movie_browser/features/SearchMovie/domain/entities/movie_detailed_entity.dart';

abstract class HiveMovieSearchRepoAbstract {
  Future<void> cacheMovieDetails(MovieDetailed movie);
  Future<MovieDetailed> getCachedMovieDetails(String id);
}

// const vars to prevent misspellings
const String MOVIEDETAILSBOX = "MovieDetailedBox";
const String SEARCHBOX = "SearchBox";

class HiveMovieSearchRepo implements HiveMovieSearchRepoAbstract {
  Box movieDetailsBox = Hive.box(MOVIEDETAILSBOX) ?? null;
  // TODO implement searchbox
  // final searchBox = Hive.box(SEARCHBOX);

  Future<void> cacheMovieDetails(MovieDetailed movie) async {
    /// expects a MovieDetailed to cache.  Will cache that movie
    movieDetailsBox ?? await _openBox(movieDetailsBox, MOVIEDETAILSBOX);

    movieDetailsBox.put('${movie.id}', movie);
  }

  Future<MovieDetailed> getCachedMovieDetails(String id) async {
    /// expects a string id as input
    /// returns the MovieDetailed if cached previously
    /// returns null otherwise
    movieDetailsBox ?? await _openBox(movieDetailsBox, MOVIEDETAILSBOX);

    return await movieDetailsBox.get('$id');
  }

  _openBox(Box box, String type) async {
    await Hive.openBox(type);
    return Hive.box(type);
  }
}

I can't think of how to test this? I want two cases, one where the box is already opened, and one case where it isn't.

Specifically, it's these lines I want to test

movieDetailsBox ?? await _openBox(movieDetailsBox, MOVIEDETAILSBOX);

_openBox(Box box, String type) async {
    await Hive.openBox(type);
    return Hive.box(type);
  }

I thought about mocking the Box object then doing something like....

when(mockHiveMovieSearchRepo.getCachedMovieDetails(some_id)).thenAnswer((_) async => object)

but wouldn't that bypass the code I want tested and always show as positive?

Thanks so much for the help

Aucun commentaire:

Enregistrer un commentaire