Membuat Aplikasi Movie dengan Flutter - Part 5: Local Contract & Use Case

Pada bagian ini kita akan membuat local contract untuk usecase melihat recently watched.

· 2 menit untuk membaca
Membuat Aplikasi Movie dengan Flutter - Part 5: Local Contract & Use Case
Photo by Tony Pepe / Unsplash

Pada bagian ini kita akan membuat use case untuk recently watched yang dimana data tersebut akan kita simpan secara lokal.

lib/features/movie/domain/repositories/movie_session_contract.dart

// ignore_for_file: one_member_abstracts

import 'package:dartz/dartz.dart';
import 'package:movie_flutter/core/domain/failures/failure.dart';
import 'package:movie_flutter/features/movie/domain/entities/movie.dart';

abstract class MovieSessionContract {
  Future<Either<Failure, Movie>> getRecentlyWatched();
}

Kemudian kita buat mock nya.

test/features/movie/domain/repositories/movie_session_contract_mock.dart

import 'package:mocktail/mocktail.dart';
import 'package:movie_flutter/features/movie/domain/repositories/movie_session_contract.dart';

class MovieSessionContractMock extends Mock implements MovieSessionContract {}

Terus kita buat test usecase nya.

test/features/movie/domain/usecases/get_recently_watched_test.dart

import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:movie_flutter/core/domain/failures/failure.dart';
import 'package:movie_flutter/core/domain/use_case.dart';
import 'package:movie_flutter/core/domain/value_object.dart';
import 'package:movie_flutter/features/movie/domain/entities/movie.dart';
import 'package:movie_flutter/features/movie/domain/entities/value_objects.dart';
import 'package:movie_flutter/features/movie/domain/usecases/get_recently_watched.dart';
import '../repositories/movie_session_contract_mock.dart';

void main() {
  late GetRecentlyWatched systemUnderTest;
  late MovieSessionContractMock contract;
  late Movie movie;
  setUp(() {
    contract = MovieSessionContractMock();
    systemUnderTest = GetRecentlyWatched(contract);
    movie = Movie(
      id: UniqueId(1),
      title: Title('Hello'),
      poster: Poster(null),
      releaseDate: DateTime.now().subtract(
        const Duration(days: 360),
      ),
      rating: Rating(8),
      trailer: Trailer(null),
    );
  });

  group('Get Recently Watched Use Case', () {
    test(
      'should return Movie if success',
      () async {
        // arrange
        when(() => contract.getRecentlyWatched()).thenAnswer(
          (_) async => right<Failure, Movie>(
            movie,
          ),
        );
        // act
        final result = await systemUnderTest(NoParam());
        final data = result.toOption().toNullable();
        // assert
        verify(() => contract.getRecentlyWatched()).called(1);
        expect(result.isRight(), true);
        expect(data != null, true);
        expect(data, movie);
      },
    );

    test(
      'should return Failure if failed',
      () async {
        // arrange
        when(() => contract.getRecentlyWatched()).thenAnswer(
          (_) async => left<Failure, Movie>(
            const Failure.localFailure(message: 'Not Found'),
          ),
        );
        // act
        final result = await systemUnderTest(NoParam());
        final data = result.toOption().toNullable();
        // assert
        verify(() => contract.getRecentlyWatched()).called(1);
        expect(result.isLeft(), true);
        expect(data, null);
      },
    );
  });
}

Dan implementasinya.

lib/features/movie/domain/usecases/get_recently_watched.dart

import 'package:dartz/dartz.dart';
import 'package:movie_flutter/core/domain/failures/failure.dart';
import 'package:movie_flutter/core/domain/use_case.dart';
import 'package:movie_flutter/features/movie/domain/entities/movie.dart';
import 'package:movie_flutter/features/movie/domain/repositories/movie_session_contract.dart';

class GetRecentlyWatched extends UseCase<Movie, NoParam> {
  GetRecentlyWatched(this._contract);
  final MovieSessionContract _contract;
  @override
  Future<Either<Failure, Movie>> call(NoParam params) async {
    return _contract.getRecentlyWatched();
  }
}

Kita jalankan test nya

Dan test nya success!.

Sampai pada tahap ini, kita telah berhasil membuat lapisan domain berupa entity, repositories dan usecase. Pada bagian selanjutnya kita akan mulai masuk ke pada implementasi repositories dan data source yang ada pada layer data.

Terima kasih telah membaca dan sampai jumpa.