<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CodingMountain</title>
    <description>The latest articles on Forem by CodingMountain (@codingmountain).</description>
    <link>https://forem.com/codingmountain</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F5912%2F23e52e4a-60b0-4e3b-9459-31930d88faec.png</url>
      <title>Forem: CodingMountain</title>
      <link>https://forem.com/codingmountain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/codingmountain"/>
    <language>en</language>
    <item>
      <title>Publish and upgrade your Flutter Package on pub.dev</title>
      <dc:creator>Safal Shrestha</dc:creator>
      <pubDate>Mon, 09 Jan 2023 11:04:11 +0000</pubDate>
      <link>https://forem.com/codingmountain/publish-and-upgrade-your-flutter-package-on-pubdev-2ilc</link>
      <guid>https://forem.com/codingmountain/publish-and-upgrade-your-flutter-package-on-pubdev-2ilc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2417fx79gjvmnudisdp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2417fx79gjvmnudisdp2.png" alt="Image description" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are developing your awesome flutter app implementation awesome functionalities and awesome widgets. Now you want to share that awesomeness with others.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you do so?
&lt;/h3&gt;

&lt;p&gt;Of course. By publishing your own awesome widgets as a package.&lt;/p&gt;

&lt;p&gt;But how do you do so?&lt;/p&gt;

&lt;p&gt;In this article, I want to show how to create and publish a package in “&lt;a href="https://pub.dev/" rel="noopener noreferrer"&gt;pub.dev&lt;/a&gt; ”.&lt;/p&gt;

&lt;p&gt;First, pick a name for your package, mine will be **hello_world **which will return a container with the text “Hello World”. Then run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter create --template=package hello_world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;in your terminal. It will create a template for your package in my case &lt;strong&gt;hello_world&lt;/strong&gt;. In the template, you will find different files. Let’s look at some of them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yfxh7ehbfahdrsb6feg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yfxh7ehbfahdrsb6feg.png" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CHANGELOG.md:&lt;/strong&gt; Here you will write the changes you made/added to the project. It is a record of changes for tracking your package and its version. It will appear in the changelog of your package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LICENSE:&lt;/strong&gt; You can add your license here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pubspec.yaml:&lt;/strong&gt; Your package dependencies go here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;README.md:&lt;/strong&gt; It will appear in the Readme of your package. It can contain brief summary of your package along with documentation, example, installation, and so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;lib:&lt;/strong&gt; It is where you will write your package&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let’s write the package.&lt;/p&gt;

&lt;p&gt;Inside the lib, we will find &lt;em&gt;hello_world.dart&lt;/em&gt;. Inside you will find the template.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library hello_world;

/// A Calculator.
class Calculator {
  /// Returns [value] plus 1.
  int addOne(int value) =&amp;gt; value + 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The library keyword is used to give the library a name, which can be used to reference it from other parts of the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s write our package.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library hello_world;

import 'package:flutter/material.dart';

class HelloWorld extends StatelessWidget {
  const HelloWorld({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Hello World!"),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Oh, and let’s initialize a Git repo in our project which helps when we need to publish our package.&lt;/p&gt;

&lt;p&gt;Now we are ready to publish our package. Right?&lt;/p&gt;

&lt;p&gt;Wrong. Before publishing the package, we still go something left to do. First, let’s organize our code.&lt;/p&gt;

&lt;p&gt;We will create a new folder *lib/src *and put our implementation/widget there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can have any folder structure, but it is recommended to use lib/src . [source](&lt;a href="https://dart.dev/guides/libraries/create-library-packages%5C" rel="noopener noreferrer"&gt;https://dart.dev/guides/libraries/create-library-packages\&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After that our project will look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeayghc5qa9xftbet8uc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeayghc5qa9xftbet8uc.png" width="308" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have moved out implementation code to &lt;em&gt;hello.dart *inside *src&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;E.g., &lt;em&gt;hello.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';

class HelloWorld extends StatelessWidget {
  const HelloWorld({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Hello World!"),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;hello_world.dart&lt;/em&gt; is used as a barrel file to export our implementation.&lt;/p&gt;

&lt;p&gt;E.g., &lt;em&gt;hello_world.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library hello_world;

export "src/hello.dart";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;A barrel file is a way to integrate multiple exports from different files into a single export.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now our package is complete. Before publishing let’s add an example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwo1apn233vya8omb3lc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwo1apn233vya8omb3lc6.png" width="788" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The example will contain a code from &lt;em&gt;example/lib/main.dart.&lt;/em&gt; We haven’t yet created an example folder.&lt;/p&gt;

&lt;p&gt;Let’s run the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter create example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After this, you will have a flutter project with a name example. Inside pubspec.yaml of example you can import your package in example with *path: ../ *instead of version.&lt;/p&gt;

&lt;p&gt;E.g. &lt;em&gt;example/pubspec.yaml&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: example
description: A new Flutter project.

publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: '&amp;gt;=2.18.5 &amp;lt;3.0.0'

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  hello_world:
    path: ../

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter:
  uses-material-design: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now my &lt;em&gt;lib/main.dart&lt;/em&gt; will be&lt;/p&gt;

&lt;p&gt;E.g &lt;em&gt;lib/main.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:hello_world/hello_world.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'My Package'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State&amp;lt;MyHomePage&amp;gt; createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: const HelloWorld(),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will be displayed in the example section of pub.dev of your package.&lt;/p&gt;

&lt;p&gt;Now let’s change CHANGELOG.md&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## 0.0.1

* Initial release of Hello World.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let’s write README.md&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Hello World
Gives Hello World widget

## Features
  - Hello world
  - Awesome
  - Null Safety

## Example Project
 Check the `example` folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, let’s add a license to our package. You can use &lt;a href="https://choosealicense.com/licenses/" rel="noopener noreferrer"&gt;**this &lt;/a&gt;**website to help you choose your license.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MIT License

Copyright (c) 2022 Safal Shrestha

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can add the homepage and repository field to your pubspec.yaml .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4pbtknztpvwymlnc7cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4pbtknztpvwymlnc7cl.png" width="401" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter pub publish --dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command will analyze our package and warns us if there is any error/issues in our packages. After that, you can publish your package to pub.dev with the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter pub publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Remember publishing is forever. After running the command, you will be asked to authenticate, and your package will be published after authenticating.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to upgrade your package. Increase your package version and run flutter pub publish again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post, you learned how to publish and upgrade your package. If you have any problem, you can reference my package &lt;a href="https://pub.dev/packages/focus_widget_list" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://pub.dev/packages/focus_widget_list" rel="noopener noreferrer"&gt;&lt;strong&gt;focus_widget_list | Flutter Package&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Learning TDD with Clean Architecture for Flutter Part IV</title>
      <dc:creator>Safal Shrestha</dc:creator>
      <pubDate>Wed, 04 Jan 2023 15:51:00 +0000</pubDate>
      <link>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-iv-16b4</link>
      <guid>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-iv-16b4</guid>
      <description>&lt;p&gt;Part &lt;strong&gt;I &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-i-46nk"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;II &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-domain-layer-part-ii-1pi5"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;III &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-data-layer-part-iii-1fff"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the final part of the series. Let’s get write into it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmffnqmizz2zujbgca3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmffnqmizz2zujbgca3l.png" alt="Presentation Layer" width="493" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Presentation Layer
&lt;/h2&gt;

&lt;p&gt;It is the UI part. Code is written to give life to the app. It is the part where users interact. It consists of pages, widgets, and state management (bloc, provider, etc).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09ya9td80mjyldws1q3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09ya9td80mjyldws1q3n.png" width="136" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;It consists of the screens to be displayed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Widgets
&lt;/h3&gt;

&lt;p&gt;It consists of the widgets that are being used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bloc
&lt;/h3&gt;

&lt;p&gt;Let’s create a bloc for the movie list state management.&lt;/p&gt;

&lt;p&gt;Eg. Movie Bloc &lt;em&gt;lib/features/movie/presentation/bloc/movie_bloc.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:movie_show/core/usecases/usecase.dart';
import 'package:movie_show/features/movie/domain/entities/movie_entity.dart';
import 'package:movie_show/features/movie/domain/usecases/get_movie_list_usecase.dart';

part 'movie_event.dart';
part 'movie_state.dart';

class MovieBloc extends Bloc&amp;lt;MovieEvent, MovieState&amp;gt; {
  final GetMovieListUsecase getMovieListUsecase;

  MovieBloc({required this.getMovieListUsecase}) : super(MovieInitial()) {
    on&amp;lt;MovieEvent&amp;gt;((event, emit) async =&amp;gt; await _onGetMovies(emit));
  }

  Future&amp;lt;void&amp;gt; _onGetMovies(Emitter&amp;lt;MovieState&amp;gt; emit) async {
    emit(MovieLoading());
    final failureOrMovieList = await getMovieListUsecase.call(NoParams());
    emit(failureOrMovieList.fold(
        (failure) =&amp;gt; const Error(message: "Server Failure"),
        (movieList) =&amp;gt; MovieLoaded(movieList: movieList)));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Eg. Movie Bloc State &lt;em&gt;lib/features/movie/presentation/bloc/movie_state.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;part of 'movie_bloc.dart';

abstract class MovieState extends Equatable {
  const MovieState();

  @override
  List&amp;lt;Object&amp;gt; get props =&amp;gt; [];
}

class MovieInitial extends MovieState {}

class MovieLoading extends MovieState {}

class MovieLoaded extends MovieState {
  final List&amp;lt;MovieEntity&amp;gt; movieList;
  const MovieLoaded({
    required this.movieList,
  });
  @override
  List&amp;lt;Object&amp;gt; get props =&amp;gt; [movieList];
}

class Error extends MovieState {
  final String message;
  const Error({
    required this.message,
  });
  @override
  List&amp;lt;Object&amp;gt; get props =&amp;gt; [message];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Eg. Movie Bloc Event &lt;em&gt;lib/features/movie/presentation/bloc/movie_event.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;part of 'movie_bloc.dart';

abstract class MovieEvent extends Equatable {
  const MovieEvent();

  @override
  List&amp;lt;Object&amp;gt; get props =&amp;gt; [];
}

class GetMovies extends MovieEvent {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After creating the bloc we will test it.&lt;/p&gt;

&lt;p&gt;Eg. Movie Bloc test: &lt;em&gt;test/features/movie/presentation/bloc/movie_bloc_test.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:movie_show/core/error/failure.dart';
import 'package:movie_show/core/usecases/usecase.dart';
import 'package:movie_show/features/movie/domain/entities/movie_entity.dart';
import 'package:movie_show/features/movie/domain/usecases/get_movie_list_usecase.dart';
import 'package:movie_show/features/movie/presentation/bloc/movie_bloc.dart';

class MockGetMovieListUsecase extends Mock implements GetMovieListUsecase {}

void main() {
  late MovieBloc movieBloc;
  late MockGetMovieListUsecase mockGetMovieListUsecase;
  final tMovieList = [
    const MovieEntity(
      movieId: 'movieId',
      title: 'title',
      thumbnail: 'thumbnail',
      movieUrl: 'movieUrl',
      unlocked: true,
    ),
    const MovieEntity(
      movieId: 'moviesIds',
      title: 'titles',
      thumbnail: 'thumbnails',
      movieUrl: 'movieUrls',
      unlocked: false,
    )
  ];
  setUp(() {
    mockGetMovieListUsecase = MockGetMovieListUsecase();
    movieBloc = MovieBloc(getMovieListUsecase: mockGetMovieListUsecase);
  });
  group('Bloc Test', () {
    test('initial state should be MovieInitial()', () async {
      //Arrange
      //Act
      //Assert
      expect(movieBloc.state, equals(MovieInitial()));
    });
    test('should get data from usecase', () async {
      //Arrange
      when(
        () =&amp;gt; mockGetMovieListUsecase.call(NoParams()),
      ).thenAnswer((_) async =&amp;gt; Right(tMovieList));
      //Act
      movieBloc.add(GetMovies());
      await untilCalled(() =&amp;gt; mockGetMovieListUsecase.call(NoParams()));
      //Assert
      verify(() =&amp;gt; mockGetMovieListUsecase.call(NoParams()));
    });
    test('should emit MovieLoaded when data is obtained succesfully', () async {
      //Arrange
      when(
        () =&amp;gt; mockGetMovieListUsecase.call(NoParams()),
      ).thenAnswer((_) async =&amp;gt; Right(tMovieList));
//Assert Later
      final expected = [
        MovieLoading(),
        MovieLoaded(movieList: tMovieList),
      ];
      expectLater(movieBloc.stream, emitsInOrder(expected));
//Act
      movieBloc.add(GetMovies());
      // print(movieBloc.stream.runtimeType);
    });
    test('should emit Error when getting data fails', () async {
      //Arrange
      when(
        () =&amp;gt; mockGetMovieListUsecase.call(NoParams()),
      ).thenAnswer((_) async =&amp;gt; Left(ServerFailure()));
//Assert Later
      final expected = [
        MovieLoading(),
        const Error(message: 'Server Failure'),
      ];
      expectLater(movieBloc.stream, emitsInOrder(expected));
//Act
      movieBloc.add(GetMovies());
      // print(movieBloc.stream.runtimeType);
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;First, we test the initial state of the bloc. During the GetMovies() event the bloc should emit two states MovieInitial() and MovieLoaded() or MovieLoading() or Error(). The state of the bloc is obtained as a stream. Here we are using the expectLater() as the bloc is executing later. So we should keep on listening for the stream of state. What about the page and widget? Shouldn’t we test it? Here we are doing the unit test, in order to test those we need to do a widget test. That’s a topic for another time. Now let’s create the UI i.e. pages and widgets. Wait a minute there arises a problem. The presentation layer only knows about the domain layer. It doesn’t know about the data layer. There seems to be no connection between those. In the presentation, we are only calling the use-case and the use-case only contains the abstract function. The UI has no way to access implementation. With all the work we have done and we can’t connect those dots.&lt;/p&gt;

&lt;p&gt;We can solve these issues by using dependency injection. It connects all the things we have been doing so far. So let’s connect the dots using &lt;a href="https://pub.dev/packages/get_it" rel="noopener noreferrer"&gt;get_it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s create a file &lt;em&gt;injection_container.dart&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Eg . &lt;em&gt;lib&lt;/em&gt;/&lt;em&gt;injection_container.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final sl = GetIt.instance;
Future&amp;lt;void&amp;gt; init() async {
//bloc
  // movie bloc
  sl.registerFactory&amp;lt;MovieBloc&amp;gt;(
    () =&amp;gt; MovieBloc(
      getMovieListUsecase: sl(),
    ),
  );
//usecase

//movie use case
  sl.registerLazySingleton&amp;lt;GetMovieListUsecase&amp;gt;(
      () =&amp;gt; GetMovieListUsecase(movieRepository: sl()));

//repository

// movie repository
  sl.registerLazySingleton&amp;lt;MovieRepository&amp;gt;(
    () =&amp;gt; MovieRepositoryImpl(
      networkInfo: sl(),
      movieListRemoteDataSource: sl(),
      awsDataSource: sl(),
    ),
  );

//data sources

sl.registerLazySingleton&amp;lt;MovieListRemoteDataSource&amp;gt;(
    () =&amp;gt; MovieListRemoteDataSourceImpl(provideFakeData: sl()),
  )

//core

//network info --&amp;gt; internet connected or not
  sl.registerLazySingleton&amp;lt;NetworkInfo&amp;gt;(
    () =&amp;gt; NetworkInfoImpl(sl()),
  );
//fake Data
  sl.registerLazySingleton&amp;lt;ProvideFakeData&amp;gt;(() =&amp;gt; ProvideFakeData());

//external
  final sharedPreferences = await SharedPreferences.getInstance();
  sl.registerLazySingleton&amp;lt;SharedPreferences&amp;gt;(
    () =&amp;gt; sharedPreferences,
  );

sl.registerLazySingleton&amp;lt;Dio&amp;gt;(
    () =&amp;gt; Dio(),
  );

sl.registerLazySingleton&amp;lt;Connectivity&amp;gt;(
    () =&amp;gt; Connectivity(),
  );

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;get_it&lt;/strong&gt; package supports creating &lt;strong&gt;singletons&lt;/strong&gt; and instance &lt;strong&gt;factories&lt;/strong&gt;. Here, we’re going to register everything as required. We will register most of them as a singleton so that our app gets only one instance of the class per lifecycle except bloc which might need multiple instances.&lt;/p&gt;

&lt;p&gt;To register, instantiate the class as usual and pass in sl() into every constructor parameter and define the constructor parameter in the same way and repeat until no constructor parameter is left.&lt;/p&gt;

&lt;p&gt;Here we provide the implementation of the abstract classes should they appear in our code. Dependency injection was the missing link between the production and test codes, where we sort of injected the dependencies manually with mocked classes. Now that we’ve implemented the &lt;strong&gt;service locator&lt;/strong&gt;, nothing can stop us from &lt;strong&gt;writing Flutter widgets&lt;/strong&gt; which will utilize every bit of code we’ve written until now by showing a fully functional UI to the user.&lt;/p&gt;

&lt;p&gt;Now you can initialize it in the &lt;em&gt;main.dart&lt;/em&gt; file and start building your UI&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to use the service locator that we created when accessing the bloc. To access movie bloc instance, you can use sl.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'injection_container.dart' as di;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await di.init();
  runApp(
    const MyApp(),
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;I won’t be doing the UI part. For reference go &lt;a href="https://resocoder.com/2019/10/29/flutter-tdd-clean-architecture-course-14-user-interface/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://bloclibrary.dev/#/" rel="noopener noreferrer"&gt;here&lt;/a&gt;(bloc)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy Coding!!&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>Learning TDD with Clean Architecture for Flutter (Data Layer) Part III</title>
      <dc:creator>Safal Shrestha</dc:creator>
      <pubDate>Thu, 22 Sep 2022 04:57:09 +0000</pubDate>
      <link>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-data-layer-part-iii-1fff</link>
      <guid>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-data-layer-part-iii-1fff</guid>
      <description>&lt;p&gt;Part I &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-i-46nk"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part II &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-domain-layer-part-ii-1pi5"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part &lt;strong&gt;IV &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-iv-16b4"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this part, let’s finish the data layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Layer
&lt;/h2&gt;

&lt;p&gt;It is the layer in which the app interacts with the outside world. It provides data to the app from the outside. It consists of low-level Data sources, Repositories which are the single source of truth for the data, and finally Models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RkqGx6eI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AYvVW937gxOeSNzzawbTeeA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RkqGx6eI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AYvVW937gxOeSNzzawbTeeA.png" alt="data layer" width="148" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Models
&lt;/h3&gt;

&lt;p&gt;Models are the entity with some additional functionalities. The data from the outside mightn’t be in the format we desired. So, models interact with this harsh environment and convert the outside data to the entity. As the relationship between model and entity is very important, we should test if the models return the entity.&lt;/p&gt;

&lt;p&gt;Eg. Movie Model Test &lt;em&gt;test/features/movie/data/models/movie_model_test.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:movie_show/features/movie/data/models/movie_model.dart';
import 'package:movie_show/features/movie/domain/entities/movie_entity.dart';

import '../../../../fixtures/fixture_reader.dart';

void main() {
  const tMovieModel = MovieModel(
    movieId:
        '''Big Buck Bunny tells the story of a giant rabbit with a heart bigger than himself. When one sunny day three rodents rudely harass him, something snaps... and the rabbit ain't no bunny anymore! In the typical cartoon tradition he prepares the nasty rodents a comical revenge.\n\nLicensed under the Creative Commons Attribution license\nhttp://[www.bigbuckbunny.org'''](http://www.bigbuckbunny.org'''),
    title: 'Big Buck Bunny',
    thumbnail: 'images/BigBuckBunny.jpg',
    movieUrl:
        "[http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4](http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4)",
    unlocked: true,
  );
  setUp(() {});
  test('MovieModel should be subclass of MovieEntity', () async {
//arrange
//act
//assert
    expect(tMovieModel, isA&amp;lt;MovieEntity&amp;gt;());
  });
  group('fromJson', () {
    test('should return a valid MovieModel', () async {
//Arrange
      final Map&amp;lt;String, dynamic&amp;gt; jsonMap =
          json.decode(await fixture('video.json'));
//Act
      final result = MovieModel.fromJson(jsonMap);
//Assert
      expect(result, tMovieModel);
    });
  });
  group('toJson', () {
    test('should return a JSON map from MovieModel', () async {
//Arrange
//Act
      final result = tMovieModel.toJson();
//Assert
      final expectedMap = {
        "movieId":
            "Big Buck Bunny tells the story of a giant rabbit with a heart bigger than himself. When one sunny day three rodents rudely harass him, something snaps... and the rabbit ain't no bunny anymore! In the typical cartoon tradition he prepares the nasty rodents a comical revenge.\n\nLicensed under the Creative Commons Attribution license\nhttp://[www.bigbuckbunny.org](http://www.bigbuckbunny.org)",
        "movieUrl":
            "[http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4](http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4)",
        "thumbnail": "images/BigBuckBunny.jpg",
        "title": "Big Buck Bunny",
        "unlocked": true
      };
      expect(result, expectedMap);
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Json file has been used from &lt;a href="https://gist.github.com/jsturgis/3b19447b304616f18657"&gt;here&lt;/a&gt;. You might be thinking why is &lt;strong&gt;movieID&lt;/strong&gt; so long. It doesn’t matter here as we are just trying to learn here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we are writing multiple tests. A test can also be grouped together using a group.&lt;/p&gt;

&lt;p&gt;At first, we make sure that the movie model extends from the movie entity and it returns the entity. Here we can see isA() keyword. It is used to check the type of object.&lt;/p&gt;

&lt;p&gt;As our model interacts with the outside world and most of the data we get from the outside is in form of JSON, our model will have a function to convert this data to an entity. So, let’s write a test for &lt;strong&gt;fromjson&lt;/strong&gt; and &lt;strong&gt;tojson&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As we are in the testing phase, let’s mimic those JSON responses.&lt;/p&gt;

&lt;p&gt;Eg. Json responses &lt;em&gt;test/fixtures/fixture_reader.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:io';  
Future&amp;lt;String&amp;gt; fixture(String name) {   
   return Future.value(File('test/fixtures/$name').readAsStringSync()); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Fixture reads from the JSON that we have created and returns them. Let’s look at our JSON file.&lt;/p&gt;

&lt;p&gt;Eg. JSON file. &lt;em&gt;test/fixtures/video.json&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "description": "Big Buck Bunny tells the story of a giant rabbit with a heart bigger than himself. When one sunny day three rodents rudely harass him, something snaps... and the rabbit ain't no bunny anymore! In the typical cartoon tradition he prepares the nasty rodents a comical revenge.\n\nLicensed under the Creative Commons Attribution license\nhttp://[www.bigbuckbunny.org](http://www.bigbuckbunny.org)",
    "sources": [
        "[http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4](http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4)"
    ],
    "subtitle": "By Blender Foundation",
    "thumb": "images/BigBuckBunny.jpg",
    "title": "Big Buck Bunny",
    "unlocked": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;In test/fixtures/video_list.json Copy json file from &lt;a href="https://gist.github.com/jsturgis/3b19447b304616f18657"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait a minute something seems wrong. It is not in the format where we defined the entity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should we go back and change the entity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, an entity is a rule that we cannot change (actually we can but we shouldn’t). The model is in charge of handling it, so the entity can get what it wants. If we run this test, the test fails (obviously as the model hasn’t been created yet), so let us write the model to make it pass.&lt;/p&gt;

&lt;p&gt;Eg. Entity of Movie &lt;em&gt;lib/features/movie/data/models/movie_model.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '../../domain/entities/movie_entity.dart';

class MovieModel extends MovieEntity {
  const MovieModel(
      {required String movieId,
      required String title,
      required String thumbnail,
      required String movieUrl,
      required bool unlocked})
      : super(
            movieId: movieId,
            title: title,
            thumbnail: thumbnail,
            movieUrl: movieUrl,
            unlocked: unlocked);
  Map&amp;lt;String, dynamic&amp;gt; toJson() {
    return &amp;lt;String, dynamic&amp;gt;{
      'movieId': movieId,
      'title': title,
      'thumbnail': thumbnail,
      'movieUrl': movieUrl,
      'unlocked': unlocked,
    };
  }

factory MovieModel.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) {
    return MovieModel(
      movieId: json['description'] as String,
      title: json['title'] as String,
      thumbnail: json['thumb'] as String,
      movieUrl: json['sources'][0] as String,
      unlocked: json['unlocked'] as bool,
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the model, you might see the &lt;strong&gt;super&lt;/strong&gt; being used. This super is responsible to change the model into an entity (super passes the parameter to its parent constructor).&lt;/p&gt;

&lt;h3&gt;
  
  
  DataSources
&lt;/h3&gt;

&lt;p&gt;Just like the name, they provide the data. They are the sources of data. There can be multiple data sources. For now, let’s go with a remote data source and create an interface for it.&lt;/p&gt;

&lt;p&gt;Eg. movie data source. &lt;em&gt;lib/features/movie/data/datasources/video_list_remote_datasource.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class MovieListRemoteDataSource {
  /// Throws a [ServerException] for all error codes.
  Future&amp;lt;List&amp;lt;MovieModel&amp;gt;&amp;gt; getMovieList();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, let’s write a test.&lt;/p&gt;

&lt;p&gt;Eg. Video List Remote DataSource Test. &lt;em&gt;test/features/movie/data/datasources/video_list_datasource_test.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:movie_show/core/error/exceptions.dart';
import 'package:movie_show/features/movie/data/datasources/video_list_remote_datasource.dart';
import 'package:movie_show/features/movie/data/models/movie_model.dart';
import 'package:movie_show/fixtures/fixture_reader.dart';

import '../../../../fixtures/fixture_reader.dart';

class MockMovie extends Mock implements MovieListRemoteDataSourceImpl {}

class MockProvideFakeData extends Mock implements ProvideFakeData {}

void main() {
  late MovieListRemoteDataSourceImpl movieListRemoteDataSourceImpl;
  late MockProvideFakeData mockProvideFakeData;
  setUp(() {
    mockProvideFakeData = MockProvideFakeData();
    movieListRemoteDataSourceImpl =
        MovieListRemoteDataSourceImpl(provideFakeData: mockProvideFakeData);
  });
  group('remote Data Source', () {
    test('should return list of movie model', () async {
      //Arrange
      when(() =&amp;gt; mockProvideFakeData.fixture('video_list.json'))
          .thenAnswer((_) async =&amp;gt; await fixture('video_list.json'));
      //Act
      final result = await movieListRemoteDataSourceImpl.getMovieList();
      //Assert
      verify(() =&amp;gt; mockProvideFakeData.fixture('video_list.json'));
      expect(result, isA&amp;lt;List&amp;lt;MovieModel&amp;gt;&amp;gt;());
    });
    test('should return serverexception if caught', () async {
      //Arrange
      when(() =&amp;gt; mockProvideFakeData.fixture('video_list.json'))
          .thenThrow(ServerException());
      //Act
      final result = movieListRemoteDataSourceImpl.getMovieList;
//Assert
      expect(() async =&amp;gt; await result.call(),
          throwsA(const TypeMatcher&amp;lt;ServerException&amp;gt;()));
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Where did the provide fake data come from? Remember data sources interact with the outside world, we are simulating the outside world with that class. When the function is supposed to throw an error, we should use &lt;strong&gt;thenthrow()&lt;/strong&gt; and call a function &lt;strong&gt;throwsA()&lt;/strong&gt; from the &lt;strong&gt;expect()&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;Eg. ProvideFake Data. &lt;em&gt;lib/fixtures/fixture_reader.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/services.dart';
class ProvideFakeData {
  Future&amp;lt;String&amp;gt; fixture(String name) async {
// for a file
    return await rootBundle.loadString("assets/$name");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let’s write the implementation of the data source so that the test can pass.&lt;/p&gt;

&lt;p&gt;Eg. movie data source. &lt;em&gt;lib/features/movie/data/datasources/video_list_remote_datasource.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

import '../../../../core/error/exceptions.dart';
import '../../../../fixtures/fixture_reader.dart';
import '../models/movie_model.dart';

abstract class MovieListRemoteDataSource {
  /// Throws a [ServerException] for all error codes.
  Future&amp;lt;List&amp;lt;MovieModel&amp;gt;&amp;gt; getMovieList();
}

class MovieListRemoteDataSourceImpl implements MovieListRemoteDataSource {
  final ProvideFakeData provideFakeData;
  MovieListRemoteDataSourceImpl({required this.provideFakeData});
  [@override](http://twitter.com/override)
  Future&amp;lt;List&amp;lt;MovieModel&amp;gt;&amp;gt; getMovieList() async {
    List&amp;lt;MovieModel&amp;gt; movieList = [];
    try {
      final jsonMap =
          json.decode(await provideFakeData.fixture('video_list.json'));
      final result = jsonMap['categories'][0]['videos'];
      for (var item in result) {
        movieList.add(MovieModel.fromJson(item));
      }
      return movieList;
    } catch (e) {
      throw ServerException();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After this, the test will pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;p&gt;It is the brain of the model deciding what to do with the data obtained from the data sources. It is the implementation of the repository defined in the domain layer.&lt;/p&gt;

&lt;p&gt;Before writing the test we create an abstraction for the dependencies that depend on the NetworkInfo.&lt;/p&gt;

&lt;p&gt;Eg . Network Info. &lt;em&gt;lib/core/network/network_info.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:connectivity/connectivity.dart';

abstract class NetworkInfo {
  Future&amp;lt;bool&amp;gt; get isConnected;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We don’t need to create the implementation of NetworkInfo as we are going to mock it (You can write implementation if you want but it won’t be used in the test). Now let’s write a test.&lt;/p&gt;

&lt;p&gt;Eg . Repository Implementation test. &lt;em&gt;test/features/movie/data/repositories/movie_repository_impl_test.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:movie_show/core/error/exceptions.dart';
import 'package:movie_show/core/error/failure.dart';
import 'package:movie_show/core/network/network_info.dart';
import 'package:movie_show/features/movie/data/datasources/video_list_remote_datasource.dart';
import 'package:movie_show/features/movie/data/models/movie_model.dart';
import 'package:movie_show/features/movie/data/repositories/movie_repository_impl.dart';
import 'package:movie_show/features/movie/domain/entities/movie_entity.dart';

class MockRemoteDataSource extends Mock implements MovieListRemoteDataSource {}

class MockNetworkInfo extends Mock implements NetworkInfo {}

void main() {
  late MovieRepositoryImpl movieRepositoryImpl;
  late MockRemoteDataSource mockRemoteDataSource;
  late MockNetworkInfo mockNetworkInfo;
  final tMovieModelList = [
    const MovieModel(
      movieId: 'movieId',
      title: 'title',
      thumbnail: 'thumbnail',
      movieUrl: 'movieUrl',
      unlocked: true,
    ),
    const MovieModel(
      movieId: 'moviesIds',
      title: 'titles',
      thumbnail: 'thumbnails',
      movieUrl: 'movieUrls',
      unlocked: false,
    )
  ];
  final List&amp;lt;MovieEntity&amp;gt; tMovieEntityList = tMovieModelList;
  setUp(() {
    mockRemoteDataSource = MockRemoteDataSource();
    mockNetworkInfo = MockNetworkInfo();
    movieRepositoryImpl = MovieRepositoryImpl(
      networkInfo: mockNetworkInfo,
      movieListRemoteDataSource: mockRemoteDataSource,
    );
  });
  group('getMovieList:', () {
    test('should check if device is online', () async {
      //Arrange
      when(
        () =&amp;gt; mockNetworkInfo.isConnected,
      ).thenAnswer((_) async =&amp;gt; true);
      await mockNetworkInfo.isConnected;
//Assert
      verify(() =&amp;gt; mockNetworkInfo.isConnected);
    });
    group('when device is online', () {
      setUp(() {
        when(
          () =&amp;gt; mockNetworkInfo.isConnected,
        ).thenAnswer((_) async =&amp;gt; true);
      });
      test('should return remote data when call is succesfull', () async {
        //Arrange
        when(
          () =&amp;gt; mockRemoteDataSource.getMovieList(),
        ).thenAnswer((_) async =&amp;gt; tMovieModelList);
        //Act
        final result = await movieRepositoryImpl.getMovieList();
//Assert
        verify(
          () =&amp;gt; mockRemoteDataSource.getMovieList(),
        );
        expect(result, equals(Right(tMovieEntityList)));
      });
      test('should return failure when call is unsuccesfull', () async {
        //Arrange
        when(
          () =&amp;gt; mockRemoteDataSource.getMovieList(),
        ).thenThrow(ServerException());
        //Act
        final result = await movieRepositoryImpl.getMovieList();
//Assert
        verify(
          () =&amp;gt; mockRemoteDataSource.getMovieList(),
        );
        expect(result, equals(Left(ServerFailure())));
      });
    });
    group('device is offline', () {
      setUp(() {
        when(
          () =&amp;gt; mockNetworkInfo.isConnected,
        ).thenAnswer((_) async =&amp;gt; false);
      });
      test('should return failure', () async {
        //Arrange
        /// No arrange as datasource is not called if no network is found
        //Act
        final result = await movieRepositoryImpl.getMovieList();
//Assert
        verifyNever(
          () =&amp;gt; mockRemoteDataSource.getMovieList(),
        );
        expect(result, equals(Left(ServerFailure())));
      });
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;While checking for exceptions, we should not call the function as it results in exceptions. It should be called within the expect() function. While writing tests we should try to consider every possible scenario. The &lt;em&gt;verifyNever&lt;/em&gt; verifies that mockRemoteDataSource.getMovieList() isn’t called.&lt;/p&gt;

&lt;p&gt;Now let’s write the implementation of the repository&lt;/p&gt;

&lt;p&gt;Eg. Movie Repository Implementation. &lt;em&gt;lib/features/movie/data/repositories/movie_repository_impl.dart&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:dartz/dartz.dart';

import '../../../../core/error/exceptions.dart';
import '../../../../core/error/failure.dart';
import '../../../../core/network/network_info.dart';
import '../../domain/entities/movie_entity.dart';
import '../../domain/repositories/movie_repository.dart';
import '../datasources/video_list_remote_datasource.dart';

class MovieRepositoryImpl implements MovieRepository {
  final NetworkInfo networkInfo;
  final MovieListRemoteDataSource movieListRemoteDataSource;
  MovieRepositoryImpl({
    required this.networkInfo,
    required this.movieListRemoteDataSource,
  });
  [@override](http://twitter.com/override)
  Future&amp;lt;Either&amp;lt;Failure, List&amp;lt;MovieEntity&amp;gt;&amp;gt;&amp;gt; getMovieList() async {
    if (await networkInfo.isConnected) {
      try {
        final movieList = await movieListRemoteDataSource.getMovieList();
        return Right(movieList);
      } on ServerException {
        return Left(ServerFailure());
      }
    } else {
      return Left(ServerFailure());
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After this, the test should pass and the data layer has been completed.&lt;/p&gt;

&lt;p&gt;Finally, we have the following file and folder&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L9Ww0R_7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AJ7HWfL0Vhnyd8UHpK3WKLw.png" alt="Data Layer in lib" width="280" height="158"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;DataLayer in lib&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U6AUO3vX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Abh5P57tMSNVXk69OSF0aAA.png" alt="Data Layer in test" width="259" height="156"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;DataLayer in test&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sptgLbxv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AGzJ7V9sdgMNKApdguG-8WA.png" alt="Fixture in test" width="279" height="130"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Fixture in test&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bQPZ9q5L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/560/1%2AfuGfw-dNIdnD4ymQVEavdQ.png" alt="Lib structure" width="280" height="376"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Lib structure&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the next part, we will finish the presentation layer and dependency injection. See you there :)&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>cleanarchitecture</category>
      <category>dart</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Learning TDD with Clean Architecture for Flutter (Domain Layer) Part II</title>
      <dc:creator>Safal Shrestha</dc:creator>
      <pubDate>Thu, 11 Aug 2022 16:49:00 +0000</pubDate>
      <link>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-domain-layer-part-ii-1pi5</link>
      <guid>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-domain-layer-part-ii-1pi5</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjryd85jvf62219jolngj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjryd85jvf62219jolngj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part &lt;strong&gt;I &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-i-46nk"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;III &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-data-layer-part-iii-1fff"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;IV &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-iv-16b4"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Welcome back to the Part II of this series. Let’s continue from where we left. Here we will begin to code and finish TDD for the domain layer.&lt;/p&gt;
&lt;h2&gt;
  
  
  TDD Clean Architecture
&lt;/h2&gt;

&lt;p&gt;Now we know a little bit about TDD and Clean Architecture, let us combine those two to get the best of both worlds. Before jumping onwards here are a few things :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; We will be writing a unit test.&lt;/li&gt;
&lt;li&gt; We will be using Mocktail to mock the dependencies.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; class MockAwsDataSource extends Mock implements AwsDataSource {} 
    // To mock class AwsDataSourece using mocktail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt; While testing any class, mock all the classes/dependencies inside it except the class we are testing and control all the functions inside those classes.&lt;/li&gt;
&lt;li&gt; You should have a similar folder structure inside the &lt;em&gt;test&lt;/em&gt; folder i.e. mimic the &lt;em&gt;lib&lt;/em&gt; folder structure inside the &lt;em&gt;test&lt;/em&gt; folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You should have basic knowledge on dart and abstraction&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Domain Layer
&lt;/h2&gt;

&lt;p&gt;It is one of the most important layers. It should remain unchanged even if all other layer changes. We should always start with the domain layer.&lt;/p&gt;

&lt;p&gt;The domain layer consists of entities, repositories, and use cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ALxYD7KSKLkGj3C2hD2DzIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ALxYD7KSKLkGj3C2hD2DzIg.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Entities
&lt;/h3&gt;

&lt;p&gt;It is a lightweight domain object and the basic data structure that we will absolutely need.&lt;/p&gt;

&lt;p&gt;Eg. Entity of Movie &lt;em&gt;lib/features/movie/domain/entities/movie_entity.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import 'package:equatable/equatable.dart';

    class MovieEntity extends Equatable {
      final String movieId;
      final String title;
      final String thumbnail;
      final String movieUrl;
      final bool unlocked;
      const MovieEntity({
        required this.movieId,
        required this.title,
        required this.thumbnail,
        required this.movieUrl,
        required this.unlocked,
      });

    @override
      List&amp;lt;Object&amp;gt; get props {
        return [
          movieId,
          title,
          thumbnail,
          movieUrl,
          unlocked,
        ];
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://pub.dev/packages/equatable" rel="noopener noreferrer"&gt;Equatable &lt;/a&gt;overrides == and hashCode for you so you don't have to waste your time writing lots of boilerplate code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;p&gt;It is in both the domain and data layer. Its definition is in the domain layer and implementation is in the data layer allowing total independence of the domain layer.&lt;/p&gt;

&lt;p&gt;Eg. Repository of Movie &lt;em&gt;lib/features/movie/domain/repositories/movie_repository.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  import 'package:dartz/dartz.dart';
    import '../../../../core/error/failure.dart';
    import '../entities/movie_entity.dart';
    abstract class MovieRepository {
      Future&amp;lt;Either&amp;lt;Failure, List&amp;lt;MovieEntity&amp;gt;&amp;gt;&amp;gt; getMovieList();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will have a method to get a list of movies, i.e. list of movie entities. &lt;em&gt;Future&amp;gt;&amp;gt;&lt;/em&gt; will ensure error handling . Let us move on. Wait a minute what is &lt;em&gt;either&lt;/em&gt; keyword? It allows a function to return between failure and List of movie entities, not both. It has been obtained from package &lt;em&gt;Dartz&lt;/em&gt; which gives functional programming capabilities to dart. &lt;em&gt;Failure&lt;/em&gt; class was defined in the &lt;em&gt;core/error&lt;/em&gt; file to define the failure of the code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In core the features, abstraction or module that is used in other features are defined&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Eg. Failure is defined in &lt;em&gt;lib/core/error/failure.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:equatable/equatable.dart';
    abstract class Failure extends Equatable {
     @override
      List&amp;lt;Object?&amp;gt; get props =&amp;gt; [];
    }
    //General Failures
    class ServerFailure extends Failure {}
    class CacheFailure extends Failure {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usecases
&lt;/h3&gt;

&lt;p&gt;Use Cases are where the business logic gets executed. It calls a repository to get data.&lt;/p&gt;

&lt;p&gt;Eg. Usecase to get movie list &lt;em&gt;lib/features/movie/domain/usecases/get_movie_list_usecase.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import 'package:dartz/dartz.dart';
    import '../../../../core/error/failure.dart';
    import '../../../../core/usecases/usecase.dart';
    import '../entities/movie_entity.dart';
    import '../repositories/movie_repository.dart';

    class GetMovieListUsecase implements UseCase&amp;lt;List&amp;lt;MovieEntity&amp;gt;, NoParams&amp;gt; {
      final MovieRepository movieRepository;
      GetMovieListUsecase({
        required this.movieRepository,
      });

    @override
      Future&amp;lt;Either&amp;lt;Failure, List&amp;lt;MovieEntity&amp;gt;&amp;gt;&amp;gt; call(NoParams params) async {
        return await movieRepository.getMovieList();
      }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;GetVideoLiseUsecase&lt;/em&gt; implements use-case inside &lt;em&gt;lib/core/use-case&lt;/em&gt; . We are defining rules for use cases there.&lt;/p&gt;

&lt;p&gt;Eg. Base use-case is defined in &lt;em&gt;lib/core/usecases/usecase.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import 'package:dartz/dartz.dart';
    import 'package:equatable/equatable.dart';
    import '../error/failure.dart';
    abstract class UseCase&amp;lt;Type, Params&amp;gt; {
      Future&amp;lt;Either&amp;lt;Failure, Type&amp;gt;&amp;gt; call(Params params);
    }

    class NoParams extends Equatable {
      @override
      List&amp;lt;Object?&amp;gt; get props =&amp;gt; [];
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7g4dzGioUVJGb7Qv8-7SOg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7g4dzGioUVJGb7Qv8-7SOg.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait a minute this was supposed to be TDD Clean Architecture. Shouldn’t we write a test first?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, before writing a use case, we should first write the test first. Just imagine the above code hasn’t been written yet for now and let’s write a test.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test file should end with ‘_test.dart’ and you can run test by typing &lt;strong&gt;&lt;em&gt;flutter test&lt;/em&gt;&lt;/strong&gt; in terminal or you can run them manually clicking run. While naming the test give it the same name as the file you are trying to test and add ‘ _test ’ to it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Eg. Test for use-case &lt;em&gt;test/features/movie/domain/usecases/get_movie_list_usecase_test.dart&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import 'package:dartz/dartz.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:mocktail/mocktail.dart';

class MockMovieRepository extends Mock implements MovieRepository {}
  void main() {
      late GetMovieListUsecase getMovieListUsecase;
      late MockMovieRepository mockMovieRepository;
      final tMovieList = [
        const MovieEntity(
          movieId: 'movieId',title: 'title',thumbnail: 'thumbnail',
      movieUrl: 'movieUrl',unlocked: true,
        ),
        const MovieEntity(
          movieId: 'movieIds',title: 'titles',thumbnail: 'thumbnails',
      movieUrl: 'movieUrls',unlocked: false,
        )   
      ];
      setUp(() {
        mockMovieRepository = MockMovieRepository();
        getMovieListUsecase =
            GetMovieListUsecase(movieRepository: mockMovieRepository);
      });
      test(
        'should get list of movie',
        () async {
          // arrange
          when(() =&amp;gt; mockMovieRepository.getMovieList())
              .thenAnswer((_) async =&amp;gt; Right(tMovieList));

    // act
          final result = await getMovieListUsecase(NoParams());

    // assert
          verify(() =&amp;gt; mockMovieRepository.getMovieList());

    expect(result, Right(tMovieList));
          verifyNoMoreInteractions(mockMovieRepository);
        },
      );
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s explain the code&lt;/p&gt;

&lt;p&gt;We are testing &lt;em&gt;GetMovieListUsecase&lt;/em&gt; in &lt;em&gt;get_movie_list_usecase.dart&lt;/em&gt; which implements a base use case in &lt;em&gt;lib/core/usecases/usecase.dart&lt;/em&gt; . &lt;em&gt;GetMovieListUsecase&lt;/em&gt; use case calls a repository for data, so the repository must be mocked to test the use case. After mocking the repository, we write the test.&lt;/p&gt;

&lt;p&gt;Now just like in the original dart file, there is the main file that will be executed. The main function contains the test.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;First, we define all the dependencies we need.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Then we instantiate them in setUp. If we look at the &lt;strong&gt;test&lt;/strong&gt; there are three parts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In &lt;strong&gt;arrange&lt;/strong&gt; we control the outcome of the functions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In &lt;strong&gt;act&lt;/strong&gt;, we run the functions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In &lt;strong&gt;assert&lt;/strong&gt;, we verify/check if the test is successful or not. &lt;strong&gt;verify&lt;/strong&gt; function is making sure that the function has been executed. expect to compare the result and &lt;strong&gt;verifyNoMoreInteractions&lt;/strong&gt; to ensure that the repository is no longer being used or interacted with.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If we look closely, we can see that the test looks like documentation explaining to us what the code is supposed to do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;You might be wondering if usecase hasn’t been created yet how do we map or visualize the test. Here comes, abstraction to the rescue . Even though getMovieListUsecase hasn’t been created , the usecase has been defined using abstract class. We can use this abstract class to visualize what the usecase class will be like and use it to write the test(most of the time). So interface/abstract class are very important in TDD. After writing the test, we write the usecase until the test in successful and refactor it as needed.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only use-case needs to be tested in the domain layer as the repository and entity have nothing to test as they are very simple.&lt;/p&gt;

&lt;p&gt;Finally, we have the following file and folder&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AOlkcfu9WbtcANI-SVN7-Gg.png" alt="Domain Layer in lib"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Domain Layer in lib&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AKdK_YDCnuGPEFsjRfIr9bw.png" alt="Domain Layer in test"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Domain Layer in test&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In my next post, we will implement TDD for the Data layer.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>tdd</category>
      <category>cleanarchitecture</category>
      <category>dart</category>
    </item>
    <item>
      <title>Learning TDD with Clean Architecture for Flutter Part I</title>
      <dc:creator>Safal Shrestha</dc:creator>
      <pubDate>Mon, 08 Aug 2022 10:49:00 +0000</pubDate>
      <link>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-i-46nk</link>
      <guid>https://forem.com/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-i-46nk</guid>
      <description>&lt;p&gt;This will be four-part series in which we will learn about TDD in Flutter.&lt;br&gt;
Part &lt;strong&gt;II &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-domain-layer-part-ii-1pi5"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;III &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-data-layer-part-iii-1fff"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Part &lt;strong&gt;IV &lt;a href="https://dev.to/codingmountain/learning-tdd-with-clean-architecture-for-flutter-part-iv-16b4"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD(Test Driven Development)
&lt;/h2&gt;

&lt;p&gt;TDD is an approach in which the test is written to validate the code that we write. Here the test is written and the code is modified to pass the test. It is also known as Test First Development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AqwfFPioDUsTxB6eG1w5BkQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AqwfFPioDUsTxB6eG1w5BkQ.png" alt="TDD"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TDD cycle defines
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Write a test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it run&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the code to make it right i.e. Refactor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat process&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  TDD Advantages
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fewer bugs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding new functionalities becomes easier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Faster in the long run&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tidier Code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Forces you to focus on one thing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clean Interfaces&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  TDD Disadvantages
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Slow Process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Faulty test code/No Silver Bullet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All members should do it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increases Complexity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design dependent&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Clean Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A25u1HBuqn542BskxxJRpXA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A25u1HBuqn542BskxxJRpXA.png" alt="Clean Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clean Architecture is also known as Domain-Driven Design. The primary idea in Clean Architecture is to make the solution adaptive, and keep the core business or application logic use cases independent of frontend and external frameworks.&lt;/p&gt;

&lt;p&gt;It produces the system that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Independent of Frameworks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independent of UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independent of Database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independent of any external agency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In clean architecture, codes are divided into layers. Inner layers are independent of the outer layer and changes can be made to the outer layer without ever touching the inner layer. It follows the &lt;em&gt;**Dependency Rule&lt;/em&gt;&lt;em&gt;.&lt;/em&gt; &lt;em&gt;This rule says that source code dependencies can only point inwards&lt;/em&gt;. Nothing in an inner circle can know anything at all about something in an outer circle. Here it contains four layers:&lt;/p&gt;

&lt;h3&gt;
  
  
  Entities
&lt;/h3&gt;

&lt;p&gt;Entities encapsulate &lt;em&gt;Enterprise-wide&lt;/em&gt; business rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter so long as the entities could be used by many different applications in the enterprise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases
&lt;/h3&gt;

&lt;p&gt;The software in this layer contains &lt;em&gt;application-specific&lt;/em&gt; business rules. It encapsulates and implements all of the use cases of the system. These use cases orchestrate the flow of data to and from the entities and direct those entities to use their &lt;em&gt;enterprise-wide&lt;/em&gt; business rules to achieve the goals of the use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface Adapters
&lt;/h3&gt;

&lt;p&gt;The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities to the format most convenient for some external agency such as the Database or the Web.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frameworks and Drivers
&lt;/h3&gt;

&lt;p&gt;The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc. Generally, you don’t write much code in this layer other than glue code that communicates to the next circle inwards.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There can be more than four layers. This diagram is only symbolic. There can be more layer as long as it follows &lt;em&gt;dependency rule&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Clean Architecture and Flutter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A1m2Zf6LtFZM_vVjRMpXfZw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A1m2Zf6LtFZM_vVjRMpXfZw.jpeg" alt="Clean Architecture in Flutter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make things clear and Flutter-specific, we are using &lt;a href="https://resocoder.com/2019/08/27/flutter-tdd-clean-architecture-course-1-explanation-project-structure/" rel="noopener noreferrer"&gt;Reso Coder’s Flutter Clean Architecture Proposal&lt;/a&gt;. It consists of three layers :&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain Layer
&lt;/h3&gt;

&lt;p&gt;It is the inner layer that shouldn’t be susceptible to the whims of changing data sources or porting our app to Angular Dart. It will contain only the core &lt;strong&gt;business logic&lt;/strong&gt; (&lt;strong&gt;&lt;em&gt;use cases&lt;/em&gt;&lt;/strong&gt;) and &lt;strong&gt;business objects&lt;/strong&gt; (&lt;strong&gt;&lt;em&gt;entities&lt;/em&gt;&lt;/strong&gt;). It should be totally &lt;em&gt;independent&lt;/em&gt; of every other layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Layer
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;data layer&lt;/strong&gt; consists of a &lt;strong&gt;Repository implementation&lt;/strong&gt; (the contract comes from the &lt;strong&gt;domain layer&lt;/strong&gt;) and &lt;strong&gt;data sources&lt;/strong&gt; — one is usually for getting remote (API) data and the other for caching that data. &lt;strong&gt;A repository&lt;/strong&gt; is where you decide if you return fresh or cached data when to cache it and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Presentation Layer
&lt;/h3&gt;

&lt;p&gt;This layer contains UI and state management approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Folder Structure
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ar9tu36PyWrak4msITx_mfA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ar9tu36PyWrak4msITx_mfA.png" alt="Folder Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, you learn a little bit about test-driven development and clean architecture. For more, head on to part II.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>tdd</category>
      <category>cleanarchitecture</category>
      <category>dart</category>
    </item>
  </channel>
</rss>
