Kotlin Koin — Android Tutorial for Beginners — Step By Step Guide
We have been using the Dependency Injection framework quite a few times like Dagger in our project.
In this blog, we are going to learn about Koin, a new dependency injection framework for Android Developers. If you are not familiar with why we need a dependency injection framework in our project, click here .
We are going to discuss,
- What is Koin?
- Understanding terminologies in Koin
- Setting up your project
- Project Structure
- Integrating Koin
What is Koin?
Koin is a DI framework for Kotlin developers, completely written in Kotin.
It is very light weighted. It supports the Kotlin DSL feature. It is one of the easy DI frameworks which doesn’t require a steep learning curve to get hold of it.
Understanding Terminologies in Koin
While working with Koin, there are few terminologies we need to understand before getting started.
- module — it creates a module in Koin which would be used by Koin to provide all the dependencies.
- single — it creates a singleton that can be used across the app as a singular instance.
- factory — it provides a bean definition, which will create a new instance each time it is injected.
- get() — it is used in the constructor of a class to provide the required dependency.
Setting up your project
Here, we are going to set up the Android Project.
Create a Project
- Start a new Android Studio Project
- Select Empty Activity and Next
- Name: Koin-Tutorial
- Package name: com.mindorks.framework.mvvm
- Language: Kotlin
- Finish
- Your starting project is ready now
Add dependencies
Add the following dependencies in the app’s build.gradle file,
Now our project is ready with dependencies.
Project Structure
For the project, we are going to follow a basic version of MVVM. Our package in the project will look like below:

We need the enum to represent the UI State. We will create that in the utils package.
We need a utility class that will be responsible to communicate the current state of Network Call to the UI Layer. We are naming that as Resource. So, create a Kotlin data class Resource inside the same utils package and add the following code.
Our utils package is ready now.
Integrating Koin
To setup Koin in your project, we would add the following in your app’s build.gradle,
This is the only required setup we need to do to get started with Koin.
Now, let’s break the further tasks in steps.
We will first create our Application class App like,
and we will update the Manifest file like,
Now, we will add the dependencies for Retrofit and Kotlin-Coroutines in the app’s build.gradle like,
Now, in the project what we will do is, we will do an API call and show a list of users.
We will also use Kotlin-Coroutine for multithreading. Now, we will create api , model , repository packages inside the data layer. It will have files like,

Then, ApiService looks like,
ApiHelper looks like,
And finally, the ApiHelperImpl looks like,
Also, for BASE_URL , we will add the following in the defaultConfig block in the app’s build.gradle file,
The User data class looks like,
Now, inside the MainRepository, we will update the code like,
Now, we are done setting up the data layer, and let’s move to the DI part of the project.
Now, we will create a package di -> module and inside it, we will create AppModule, ViewModelModule, and RepositoryModule.
Inside AppModule first, we will create the functions we want to provide as dependencies. We will update the file like,
Now, to create the file as a supported module for Koin, we will pass the functions as singleton instance to the module. The module is a collection of dependencies we are going to provide to the application. We will create a variable like,
and inside the module, we will pass the single instance of all the functions we created like,
Here, to provide the dependency as a singleton instance we use single<> and inside it, we will pass the function which will return the dependency as an instance to be used across the app.
We are using get() here to pass the dependency to the constructor. Using get it will only provide the constructor whose instance is already been provided by Koin.
Now, let’s update the RepositoryModule. Here, we will provide the MainRepository instance by,
Here, MainRepository requires ApiHelper in the constructor which will be provided by the Koin here.
And for ApiHelper, we would need the ApiHelperImpl part to be provided which is the extension for ApiHelper. Now, to pass the ApiHelper as a param, we need to provide it as well from the module.
To provide the ApiHelperImpl in the module, we will update the code and create a single instance like,
Here, we are providing a type if ApiHelper, and returning ApiHelperImpl and in ApiHelperImpl it takes ApiService as a constructor parameter which we are already providing from provideApiService function.
Now, we are going to use a MainViewModel for updating the UI. To provide dependencies in ViewModel we will update the ViewModelModule like,
Here, you can see we are not using single, and in place of that we are using viewModel and inside it, we resolve the dependencies which we are providing from appModule.
Now, we are done providing the dependencies. Let us start now by injecting the dependencies.
Now, let’s start designing our ViewModel. We will update the ViewModel like,
Here, we are passing MainRepository and NetworkHelper in the constructor of the ViewModel.
Here, we are fetching the users in the init block and inside the viewModelScope, we will check for internet connectivity and if the connectivity is ok then we go through the API call or else we set the value to LiveData with an error. This user LiveData is then observed in the MainActivity to display the items in the recyclerView.
NetworkHelper looks like,
Now, we need to create the instance of ViewModel in the MainActivity so the values passed in the constructor of the ViewModel are passed to it.
To pass the instance of ViewModel we will create a variable called mainViewModel like,
Here, by viewModel() creates the instance for the ViewModel and it will also resolve the dependency required by it.
Now, the MainActivity looks like,
and the MainAdapter looks like,
Now, we are almost done with setting up the project.
To run the app successfully, we will add the required permissions like,
and to initialize Koin in the project we will update the onCreate() of the application like,
Here, we are passing the androidContext to the Koin container which you can see we are using it in the appModule while providing the NetworkHelper class.
We are also passing all the modules which we created in the di/modules package.
Now, we are done with the project and if you run the project, you would see the list of users being populated in the recyclerView.
Android
This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. You need around 10/15 min to do the tutorial.
Get the code
Gradle Setup
Add the Koin Android dependency like below:
Application Overview
The idea of the application is to manage a list of users, and display it in our MainActivity class with a Presenter or a ViewModel:
Users -> UserRepository -> (Presenter or ViewModel) -> MainActivity
The "User" Data
We will manage a collection of Users. Here is the data class:
We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the UserRepository interface and its implementation:
The Koin module
Use the module function to declare a Koin module. A Koin module is the place where we define all our components to be injected.
Let's declare our first component. We want a singleton of UserRepository , by creating an instance of UserRepositoryImpl
Displaying User with Presenter
Let's write a presenter component to display a user:
UserRepository is referenced in UserPresenter`s constructor
We declare UserPresenter in our Koin module. We declare it as a factory definition, to not keep any instance in memory (avoid any leak with Android lifecycle):
The get() function allow to ask Koin to resolve the needed dependency.
Injecting Dependencies in Android
The UserPresenter component will be created, resolving the UserRepository instance with it. To get it into our Activity, let's inject it with the by inject() delegate function:
That's it, your app is ready.
The by inject() function allows us to retrieve Koin instances, in Android components runtime (Activity, fragment, Service. )
Start Koin
We need to start Koin with our Android application. Just call the startKoin() function in the application's main entry point, our MainApplication class:
The modules() function in startKoin load the given list of modules
Koin module: classic or constructor DSL?
Here is the Koin moduel declaration for our app:
We can write it in a more compact way, by using constructors:
Verifying your App!
We can ensure that our Koin configuration is good before launching our app, by verifying our Koin configuration with a simple JUnit Test.
Gradle Setup
Add the Koin Android dependency like below:
Checking your modules
The verify() function allow to verify the given Koin modules:
With just a JUnit test, you can ensure your definitions configuration are not missing anything!
Koin — библиотека для внедрения зависимостей, написанная на чистом Kotlin
Для будущих студентов курса «Android Developer. Professional» подготовили перевод полезной статьи.
Также приглашаем принять участие в открытом вебинаре на тему «Пишем Gradle plugin»
О чем эта статья
Вы узнаете, как с помощью модулей Koin ограничивать область живучести зависимостей, относящихся к конкретному компоненту. Вы также познакомитесь со стандартными областями Koin и способами работы с настраиваемыми областями.
Введение
Разработчики ОС Android не рекомендуют использовать внедрение зависимостей (Dependency Injection, DI (англ.)), если в вашем приложении три экрана или меньше. Но если их больше, лучше применить DI.
Популярный способ реализации DI в Android-приложениях основан на фреймворке Dagger. Но он требует глубокого изучения. Одна из лучших альтернатив этому фреймворку — Koin, библиотека, написанная на чистом Kotlin.
Если вы уже пользовались Dagger или любой другой библиотекой для DI, то, скорее всего, знаете, насколько важен в этом процессе механизм временной области (scope). Он позволяет определять, в каких случаях нужно получать один и тот же зависимый объект, а в каких — новый. Он также помогает освобождать невостребованные ресурсы и память.
Области в Koin
Концепция области в Koin аналогична таковой в Android. Она позволяет, например, ограничить область живучести модели представления (ViewModel) до определенной активности и использовать эту модель во фрагментах, которыми наполняется активность.
Как правило, в Koin три вида временных областей.
single (одиночный объект) — создается объект, который сохраняется в течение всего периода существования контейнера (аналогично синглтону);
factory (фабрика объектов) — каждый раз создается новый объект, без сохранения в контейнере (совместное использование невозможно);
scoped (объект в области) — создается объект, который сохраняется в рамках периода существования связанной временной области.
Область вида single при каждом запросе возвращает один и тот же экземпляр, а factory каждый раз возвращает новый экземпляр.
Настраиваемая область
Стандартные области single и factory в Koin живут в течение жизненного цикла модулей Koin. Однако в реальных сценариях использования требования к внедрению зависимостей будут отличаться.
Зависимости обычно нужны только на определенный период времени. Например, репозиторий OnBoardRepository в Android-приложении требуется только при регистрации пользователя. Как только пользователь авторизуется, удержание этого репозитория в памяти станет лишней тратой ресурсов.
Чтобы добиться нужного поведения в Koin, можно воспользоваться API для работы с временными областями. В модуле Koin можно создать область со строковым квалификатором и объявить зависимости внутри нее с помощью уникальных квалификаторов. Давайте сделаем это шаг за шагом.
Шаг 1
Сначала создадим модуль, объявим пустую область и присвоим ей имя. В данном случае мы дали области имя CustomScope . Вы можете назвать ее в соответствии со своими требованиями. Вот как это выглядит:
Шаг 2
Следующим шагом объявим необходимые зависимости с использованием областей single и factory в соответствии с требованиями проекта. Ключевой момент заключается в присвоении областям уникальных квалификаторов. Вот так:
Шаг 3
Мы закончили настройку в модуле Koin. На этом шаге нам нужно создать область из того компонента, из которого мы импортируем нужные зависимости. Обычно области создаются из Android-компонентов, например Activity, Fragment и т. п.
Чтобы создать область, сначала нам нужно получить существующий экземпляр компонента Koin, а затем вызвать функцию createScope, передав ей идентификатор и имя области.
Получив CustomScope как значение параметра имени, Koin будет искать область, которую мы объявили под этим именем в модулях Koin. ScopeNameID — это идентификатор, который мы применяем, чтобы отличать одну область от другой. Он используется на внутреннем уровне в качестве ключа для поиска этой области.
Если вы обращаетесь к областям или создаете их из нескольких Android-компонентов, то вместо функции createScope рекомендуется использовать функцию getOrCreateScope . Из названий этих функций очевидно, что они делают.
Шаг 4
Наконец, создаем экземпляр зависимости, которую хотим использовать. Мы сделали это с помощью созданной нами области. Вот что получилось.
scopedName и factoryName — это квалификаторы, которые мы объявили внутри модуля Koin на шаге 2.
Шаг 5
Чтобы избавиться от зависимостей, созданных посредством stringQualifiedScope, в частности sampleclass , необходимо вызвать функцию close . Например, если вы хотите избавиться от созданных в этой области зависимостей при уничтожении активности, то нужно вызвать функцию close в рамках соответствующего метода onDestroy . Вот так:
Koin-Android
Выше описан общий подход к ограничению живучести зависимостей определенной временной областью. Его можно применять на любой платформе, поддерживаемой Koin. Будучи Android-разработчиком, теперь я бы хотел совместить механизмы области Koin и области жизненного цикла, чтобы свести к минимуму работу, которую мне приходится делать при каждом создании активности.
Для этого необходимо импортировать библиотеки Koin-Android. Добавьте следующие строки в узел dependencies файла build.gradle уровня приложения:
Теперь с целью сократить шаблонный код мы хотим, например, автоматически закрывать область в рамках метода onDestroy компонента Android. Это можно сделать путем привязки Koin к импорту зависимостей посредством lifecyclescope .
Для начала необходимо создать в модуле Koin область для зависимостей с компонентами Android. Как это сделать:
scoping dependency with android activity
Затем нужно выполнить внедрение зависимости в активности при помощи lifecyclescope :
Это позволит закрывать область при уничтожении активности, избавив нас от ручных операций. Вот так выглядит наш код:
Такой подход позволит автоматизировать работу по созданию областей, назначению квалификаторов и уничтожению областей. Кажется, что это простые действия, их можно выполнить и вручную. Но повторяющуюся работу важно автоматизировать, и по мере развития приложения это становится очевидно.
Дополнительные материалы
Подробнее о внедрении зависимостей читайте в другой статье о библиотеке Koin.
На этом все. Надеюсь, вы узнали что-то полезное для себя. Спасибо за внимание!
Подробнее о курсе «Android Developer. Professional». Записаться на открытый урок «Пишем Gradle plugin» можно здесь.
Dependency Injection With Koin
In this tutorial, you’ll get to know Koin, one of the most popular new frameworks for dependency injection. By Pablo L. Sordo Martinez.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Already a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Already a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Already a member of Kodeco? Sign in
Share this
Contents
Dependency Injection With Koin
- DI: A “New” Old Friend
- To DI or Not to DI?
- Using Koin to Simplify DI
- Koin Basics
- Getting Started
- Building Mark Me!
- Adding Koin to the Project
- Defining Dependencies
- Starting Koin
- Injecting Objects
- Finishing Up!
- App Performance Analysis
- Testing: Insert Koin
- Checking the Approach
- Where to Go From Here?
Dependency Injection (DI) is one of those “new” concepts that keeps showing up in every blog post on the Internet. In fact, the idea is not new, but a notion that gets revisited from time to time. Mastering DI will allow you to handle large and complex applications in a more convenient way.
In this tutorial, you’ll get to know Koin, one of the most popular new frameworks for DI. You’ll start by learning the basics of DI and how your Android projects can take advantage of it. You’ll then apply it to a sample app that adopts Koin as a DI framework and illustrates its benefits.
DI: A “New” Old Friend
Believe it or not, many Android developers have been using DI since their very first applications. However, most new developers haven’t used any DI framework, such as Dagger 2, on their first projects. This sounds ridiculous, but it’s true. How? Follows a recap of the basics of DI.

In the illustration above, ClassA uses an object instantiated, or created, by itself, whereas ClassB just employs an object instance, regardless of where it comes from. So, it can be stated that DI means that a specific entity or class instance can obtain any dependency it needs from the outer world. In other words, the class is not concerned how it gets a dependency — just how to use it.
That’s great, but how do you give a dependency to an object? There are two main options:
- Pass dependencies through the object constructor.
- Use a DI framework.
Using one or the other depends on the developer, who should based his decision according to the size and complexity of the application. For more information about DI, check out this helpful resource.
To DI or Not to DI?
So what are the pros and cons of using DI in your project? To help you with the answer, take a look at the SOLID principles of object-oriented programming, which are five principles that improve the reusability of code and reduce need to refactor any class. DI is directly related with 2 of these pillars, specifically Single Responsibility Principle and Dependency Inversion. Briefly explained
- Single Responsibility Principle states that every class or module in a program is responsible for just a single piece of that program’s functionality.
- Dependency Inversion states that high level modules should not depend on low level modules; both should depend on abstractions.
DI supports these goals by decoupling the creation and the usage of an object. Thus, it allows you to replace dependencies without changing the class that uses them and also reduces the risk of modifying a class because one of its dependencies changed.
This makes DI a great option when an application is expected to grow considerably in size and/or complexity.
Using Koin to Simplify DI
So, why use Koin rather than one of the other DI frameworks? The answer: Koin is more concise and straightforward than the others.
Take the popular Dagger 2 as an example. To use Dagger 2, you first need to become familiar with concepts like module and component and annotations such as @Inject. While the steep learning curve for this framework eventually pays off, to get the most out of it, you still have to learn some advanced concepts such as scope and subcomponents.
In contrast, Koin allows you to simply declare modules, which include potential dependencies, to be used in the project and directly inject them in the class of interest.
Koin Basics
According to the official documentation, you can start using Koin in three simple stages:
- Declare a module: Defines those entities which will be injected at some point in the app.
- Start Koin: A single line, startKoin(this, listOf(applicationModule)) , allows you to launch the DI process and indicate which modules will be available when needed, in this case, only applicationModule .
- Perform an injection:
In consonance with Kotlin features, Koin allows to perform lazy injections in a very convenient way.
One limitation when using Koin is that you can only inject dependencies in Activity classes out of the box. In order to inject dependencies in other class types, you must do it through the corresponding constructors. To solve this problem, Koin allows classes to conform to the KoinComponent interface, so that injections are possible on non- Activity classes. You will see an example of this later on.
Getting Started
Now that the theory is clear, time to get to the action! From this section on, you’ll create an application named Mark me!. You’ll see how an application can include DI while following a proper architecture that advocates for the separation of concerns. You’ll use the popular model-view-presenter (MVP) as the architectural pattern in the presentation layer.
Begin by downloading the starter project using the Download Materials button at the top or bottom of the tutorial. The starter project contains the basic skeleton app and some assets.

The code is organized by functional modules, specifically splash, main and feature. Moreover, the application includes auxiliary packages such as di, for DI, repository, including database feature, model and utils.
Build and run the starter project.
![]() |
![]() |
![]() |
As you can see, the application looks finished. However, before it can function, you still need to add all of the logic. If you tap on either the Attendance or Grading buttons, the application will report a crash due to the lack of implementation of certain functionalities.
Remember that, by default, Android Studio includes the following line in methods overridden from interfaces:
This will cause a crash until this snippet gets replaced with a proper method implementation.
Building Mark Me!
In this section, you’ll incorporate Koin as the DI framework for the application skeleton provided in the starter project.
Mark me! is an app designed for teachers. It allows a teacher to register the attendance and grading for a class.
The starter AndroidManifest.xml file shows three Activity items:
- SplashActivity includes the MAIN intent-filter .
- MainActivity allows the user to navigate to two features, Attendance and Grading.
- FeatureActivity actually implements the mentioned features.
The app skeleton includes the Student class defined in the Data.kt file in the model package. The project also contains a pair of adapters in the feature package. These implementations do not directly relate to the topic of this tutorial, but feel free to have a look at them and analyze their behavior.
Take some time to inspect the rest of the starter project and all the features included out-of-the-box, such as the resource files strings.xml, dimens.xml and styles.xml.
Adding Koin to the Project
First, you’ll add Koin to the app dependencies. Open the project build.gradle and add the following line in the ext block of the buildscript object:
Then, refer to the build.gradle of the app module and include the next dependency in the corresponding section:
Now, sync your project and you’ll be ready to start using Koin.
Defining Dependencies
Once you’ve added Koin to the project, you can start defining the dependencies that will be injected in your code when required.
If you review the project, you’ll see that, to finish Mark me!, you need to indicate whether the information will save in a database or the user preferences. Create a package di and a new file Modules.kt where you’ll define the entities to be provided.

Then, add the following snippet, taking care to import what the IDE suggests in each case.
As you can see, the above code creates a new Koin module , which includes several important entities. Keep in mind:
- The module is marked as override , which means that its content will override any other definition within the application.
- A factory is a definition that will give you a new instance each time you ask for this object type. In other words, it represents a normal object. Any presenter involved in the application will be injected in the view instance in this way.
- single depicts a singleton component such as an instance that is unique across the application. This is typically intended for repositories, databases, etc.
Starting Koin
Since the dependency module is already defined, you only need to declare its availability. Open BaseApplication.kt and include the following snippet, making sure the imports are there as well:
As you can see, the applicationModule now includes the list of dependency modules for Koin. Next, make this class visible in the Manifest as the application class:
Injecting Objects
As previously stated, DI helps make code easier to reuse and test. Taking into account that you are using an MVP architecture implementation, the aim is to make any presenter in the app as decoupled as possible. In other words, presenters will receive but not instantiate other classes.
Start by modifying how the SplashActivity instantiates the presenter.
Initially, you can see that it is created in a lazy way on this line:
However, when you use DI, the line will look like this:
Now, splashPresenter gets lazily injected when needed. The expression parametersOf() is part of the Koin library and allows you to indicate input arguments for the object constructor. If you recall in the Modules.kt file, you defined a factory to return a new SplashContract.Presenter when a SplashContract.View is given. In this case, the SplashActivity is the SplashContract.View and is passed into the factory through parametersOf() .
Similar to the previous module, you also need to update how MainActivity obtains its presenter. The new form should be:
Now the feature package content needs some updating. In FeatureActivity , change the presenter invocation by replacing:
Now, complete the method onResume by adding:
This tells the presenter to load any persistent data available. If you happen to run the project right now, you will get a crash on this precise line since loadPersistedData doesn’t have implementation yet. Don’t worry, you’re going to fix this.
A bit further in the code, replace a pair of TODO s as follows:
When the user stores any data, a message will appear thanks to showToastMessage . You’ll use onPersistedDataLoaded to publish the fetched data in a list. Obviously, you still need to define updateData .
Open the RwAdapter interface and paste the following abstract method there:
You’ll see that both FeatureGradingAdapter and FeatureAttendanceAdapter demand an implementation for this method. For FeatureGradingAdapter , add the following:
The proposal for FeatureAttendanceAdapter is:
As you can see, the implementations are pretty similar but not exactly the same. In the first implementation, the changes to the attendance list are individually notified to the adapter, while in the second implementation, the whole grading list is changed as a group at the end of the loop. The only reason for this difference is to show you two possible approaches.
Finally, in FeaturePresenter , modify how the repository instantiates the so that it looks like this:
Don’t forget to turn the class into a KoinComponent .
Recall that Koin cannot inject non- Activity objects out of the box. In this case, since FeaturePresenter is not an instance of Activity , you must add the KoinComponent interface to the class.
Now, it’s time to provide a proper definition for loadPersistedData , which will end up looking like this:
Again, don’t be upset if you run your code now and you get a crash since you haven’t provided any definition for fetchFromDb yet.
Finishing Up!
Last, you’ll work on the repository module — specifically, the singleton class AppRepository . When you open it up, you will see a few TODO s to get rid off. Time to tackle them!
Start by adding these two constants at the beginning of the file, before the class definition, so that they are available when needed:
Then, proceed by replacing the first method in AppRepository , turning it into this:
The method asynchronously inserts a list in the database and notifies it through a message in a lambda callback.
Once you add the above snippet, you’ll get an unresolved reference error because database was never injected into AppRepository . This entity refers to the Room implementation set up in the project. This entity was also defined within the app dependencies.
Add the next line right after the class header,
and make sure AppRepository implements the KoinComponent interface.
The next method to fill in allows you to save data in the app SharedPreferences . Again, it uses Anko to perform the task in the background by using doAsync and to notify it in the main thread by using uiThread :
The last two methods implement fetching data from the database and the preferences, respectively.
The only difference between the two methods above is that the database queries are performed in a worker thread, not the main one.
And with that, you have finished implementing Mark me! Congratulations!
App Performance Analysis
Once completed, you should have the app up and running as in the following Mark me! demo video:
When started, the splash screen appears for just a few seconds, and then it jumps directly to MainActivity. From this screen the user can navigate to either of the available features: Attendance or Grading. Both of them provide a list that shows certain information about a class of students.
You can gracefully scroll along these lists and check/uncheck in one or several student registers. Tapping on the corresponding buttons saves the selections. The navigation is handled by the Toolbar and Back Arrow events.
Testing: Insert Koin
To properly asses a DI framework, you need to know how well it behaves when it comes to a unit test. Good news! Koin perfectly addresses this need.
First, you’ll add some dependencies to the app module build.gradle :
The first library brings in Koin DSL, version 1.0.2 in this case, for testing, whereas the second adds extra features to Mockito so it can work with Kotlin.
Generally speaking, unit tests make sense on non-Android layers since you want to check your logic, but not the framework itself. Since this project uses MVP as the architecture pattern, presenters should be the target.
In this example, you’re only going to check that a method is called when a certain condition happens, which will prove the compatibility and convenience of using Koin for testing.
Checking the Approach
According to the above, create a file FeaturePresenterTest.kt in the test folder.

Then, add the following snippet:
While the code is fairly straightforward, here are some things to keep in mind:
- The class must implement the KoinTest interface.
- All the elements used must be instantiated or injected, even if you are not using them directly, like the view . Since the Android OS does not allow you to invoke Activity objects, the view has to be directly mocked.
- Koin needs to start normally so that injections take place, including all of the dependency modules.
- All objects not being tested have to be mocked. In Koin, you can use declareMock for those injected objects.
- It’s good practice to use descriptive names for your methods. Remember that you can use « to enclose a name with whitespaces.
- argumentCaptor allows you to grab a value or variable and use it later with any Mockito expression. This is required when using Koin.
- Since you’re checking the presenter, invoke one of its methods with the appropriate arguments.
- This line is where the evaluation actually happens. In this case, you verify that the add2Db method from the repository gets called. If you remember the FeaturePresenter class, this should be the case when invoking onSave2DbClick . The eq method is also mandatory due to limitations between Kotlin and Mockito.
- Always remember to stop Koin.
Run the test and make sure everything passes!
Where to Go From Here?
You can download the fully finished sample project using the Download Materials button at the top or bottom of the tutorial.
While there are several good references about DI, and Koin in particular, the best source may be the official documentation, which is rather concise and self-explanatory.
Articles like this one make starting to work with Koin much easier. This article is a more practical example, which may help you on your first attempts.
If you want to keep working with the sample app you’ve just finished, try replacing the presentation layer architecture with MVVM. This pattern is becoming very popular in the field, especially after the Google I/O 2017 conference, where it was incorporated into the Android Architecture Components (AAC). Koin includes a specific DSL classes to handle this new ViewModel stuff.
I hope you enjoyed this tutorial about Koin. If you have any questions or comments, please join the forum discussion below!
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!


