Blog-Image
  • Codeaamy
  • March 9, 2024

  • 0 Comments

Unit Test In Flutter

This is the second article in the “Master Testing in Flutter” series. The first article was an introduction to Testing and different types of tests in Flutter. If you have not read that, I would advise you to read that article here before you continue with the Unit Test. Here is the list of other articles in this series, in case you want to read it.

let’s start with Unit Testing in Flutter. In unit tests, we test a small function, method or class. This helps us to check if the function is running as expected or if there are any issues in that block of code that we have just written.

In this article, we are going over the following topics.

  • Understanding the project.
  • Writing first unit test
  • Testing HTTP function
  • Mocking data for HTTP function.
  • Testing ChangeNotifier.
  • Using mocktail for Mocking data.

What Are We Going To Test

Working of a Todo Application

Above you can see a Todo Application which has a login screen which takes an email and password. to authenticate the user and navigate the user Todos screen where we display a list of all the todos. The login form has a validator which checks for email and password length. The Todos on the screen are fetched from an HTTP get request.

I wanted to keep the main app simple so that we can have more focus on the testing.

Understanding the Project

You can download the Starter Project from here -> Testing In Flutter(Follow me on GitHub 🥹). Open the starter project in you your favourite. I am using VS Code, but you can use Android Studio or any other IDE which you are comfortable with. This is what you will have.

Todo App Starter
Structure of the Project.

The model folds consist of the Todo Model which helps us to display the Todo on the Screen.

The Notifier folder has two notifier classes — LoginNotifier and TodoNotifier which extends ChangeNotifier. These notifiers will be used to manage the State of the App and also provide the required dependencies.

Pages folder consists of the UI Pages — LoginPage and AllTodoPage. The services folder has the TodoService which is responsible for fetching the Todos from the http request.

key_constants.dart contains some constants and mock data. Lets ignore that for now.

We have already added some packages that we are going to need for the testing and our application. Here flutter_test and integration_test is responsible for running tests and mocktail is used to mock the data.

  cupertino_icons: ^1.0.2
  flutter_riverpod: ^2.2.0
  http: ^0.13.5

dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test:
    sdk: flutter    
  flutter_lints: ^2.0.0
  mocktail: ^0.3.0

We will be using our test folder to write all the tests.

Writing Your First Unit Test

Ok, we have explored a lot in theory and now its time to write your First Unit Test.

Create a new file named todo_json_test.dart inside the test folder.

as you know in flutter we need main method to run our app, just like that, we need main method to run our tests also.

Understanding components of flutter_test

To test the Flutter application we need functions which will help us to run the test code. We get those functions from flutter’s official package flutter_test . It has already been implemented in pubspec.yaml .

lets see some of the components that we we will need for Unit Test. The rest of the components will be explored later on.

  • test() — a test function which helps to run tests of Flutter app. This function takes a String (name of the Test) and callback body function where we will be writing our test.
  • expect(actual, matcher) — expect function has two parameters; actual and matcher actual is the data that we get, and compare with the matcher value. If the actual and matcher value matches, the test passes and if these values do not match, the test fails.

Testing the Todo Model

inside the main() function let us write the test to test the todo model

void main() {
  test('Todo json test', () {
    final todo = Todo(1, 'title', false, 1);
    
    expect(todo.id, 1);
    expect(todo.todo, 'title');
    expect(todo.completed, false);
    expect(todo.userId, 1);
  });
}

Create a todo object with dummy data, and then let’s test the todo object. Here we expect each value with the dummy data that we have given. This is to test the Model data we have created. If we change the Model data in future, this test will fail and we will notice the change,

Now click on the run to run the written test and you will see the test passing and green ticks on the left of the test.

Running todo model test

Now let us change some of the values of matcher in expect function and re-run the test. The test will fail.

Failed Unit test as actual and matcher values are not matching.

This is how we can check if the written function is as per expectation or if something different is happening. That’s why a unit test is important.

Unit Test of an HTTP Function

An application is almost incomplete without making an HTTP request either to send some data or get some data from the backend. These are very crucial functions in an app cause chances are very high that there might be bugs in fetching and parsing the data, so testing the HTTP function is very important.

But there are times when testing we might face internet issues which can fail the test and give improper test results, hence when we test an HTTP function we have to mock the data.

Mocking Data

Mocking data means, passing dummy or mock data as per the required module to test a function or a widget.

We have already created the mock data that we are going to use. Navigate to key_constants.dart and scroll down to mockTodos .

final mockTodos = jsonEncode(data);

final data = {
  "todos": [
    {"id": 1, "todo": "Create testing blog", "completed": true, "userId": 1}
  ],
};

You can see data is an exact replica of the response that you get from the HTTP function. This mock data will be used to test the HTTP function.

Navigate to todo_json_test.dart and below the previous test inside the main() add the following code.

  test('Todo Service MOCK HTTP', () async {
    Future<Response> _mockHttp(Request request) async {
      if (request.url.toString().startsWith('https://dummyjson.com/todo')) { //
        return Response(mockTodos, 200,
            headers: {HttpHeaders.contentTypeHeader: 'application/json'});
      }

      return throw Exception('failed');
    }

    final apiService = TodoService(MockClient(_mockHttp));

    final quotes = await apiService.getTodos();

    expect(quotes.first.id, 1);
    expect(quotes.first.todo, 'Create testing blog');
    expect(quotes.first.completed, true);
    expect(quotes.first.userId, 1);
  });
  • Create a Future function _mockHttp(Request request) which will return the mock data as the response when you call the function.
  • At first, you check if the API URL starts with the same API URL that you have in the real function. If the API matches you return the response with mockTodo and the response code as 200.
  • Create a TodoService variable which takes MockClient as an HttpClient.
  • You call getTodos() and save the response in the variable named quotes.
  • expect() function checks the matcher value with the actual value of the response
  • The mock values are returned from the _mockHttp function when getTodo function is called.

Run the test and it should pass. If you change the URL or the matcher value the test function will fail. This helps us to test the response and URL that is used in the HTTP function.

As mentioned above Unit Tests are used to test a function or a class. Here we have used Unit Tests to test the HTTP function which makes a GET request to fetch todos from the API.

Here I conclude the second article from the Master Testing in Flutter Series. In the next Blog, we will explore How to Unit Test the ChangeNotifier that we have used in the app to manage the state and dependencies of the Application.

If you want to check out the rest of the blogs from the testing Series here is a list of all the blogs present. I would still address if you follow this guide step by step.

Thank You for reading my blog, if you have any doubts or recommendations please let me know in the comment section below. I would like to know what are the other way to globally listen to network connectivity.

You have 50 Claps per day. Claps do Motivate us to keep writing. Gotta Use Them All

Tags

Leave A Comment