:books: Android Sample App using modular, clean, s...
# android
m
📚 Android Sample App using modular, clean, scalable, testable Architecture written in Kotlin that presents modern 2019 approach to Android application development, latest tech-stack and best practices. Application is based, apply and strictly complies with each of the following 5 points: • A single-activity architecture, using the Navigation component to manage fragment operations. • Android architecture components, part of Android Jetpack give to project a robust design, testable and maintainable. • Pattern Model-View-ViewModel (MVVM) facilitating separation of development of the graphical user interface. • S.O.L.I.D design principles intended to make software designs more understandable, flexible and maintainable. • Modular app architecture allows being developed features in isolation, independently from other features. For more technical details please check the project readme. Project link: https://github.com/VMadalin/kotlin-sample-app
👏 10
w
I only glanced over the code, why do you use
@VisibleForTesting
for injected parameters?
m
Thanks for your feedback. Correct me please if I’m wrong. Exist 3 ways to tests injected classes especially with private constructor params: 1. Make them always public (discarded) 2. Make them visible only on tests via
@VisibleForTesting
for mocking it. 3. Inject dagger graph but override some modules providers with mocks. Similar to this:
Copy code
class TestModuleA : ModuleA() {

       @Provides
       override fun provideObject() = mock()
Personally I chose the second one, but the both are correct.
w
Not sure I follow, in the unit tests you still simply pass mocked repositories etc. to a view model
And you have references to the mocks in tests, you don’t need to refer to viewmodel’s fields directly, am I missing something?
m
I absolutely agree with you and now understand exactly why you said that. Normally isn’t necessary to add
@VisibleForTesting
on constructor params exactly for reason what you said. But in my case I also have unit tests the provider dagger modules and I need to have access to the variable to compare if the same instance what I provided when Inject the class.
w
I see now 🙂 That’s why I go for
@Inject
annotations on classes themselves, and models modules only contain bindings and scopes. This way there’s nothing to test in fact
👍 2
a
If you have to navigate from one feature to another, let’s say from Favorites to Detail page of the Favorite Marvel item, then you have to depend on the respective feature module….right? But this goes against the modularization architecture.
👍🏻 1
m
Thank you @axehit for your question. First of all it’s so important when work with modules to know exactly what you need and think about how to divide them, and how the navigate between them. For that is so important to have all navigation graphs under same module,
:app
or in this case
:home
. Because is the only thing what you need for open the detail screen in this : You need to add the following action on `navigation_characters_favorites_graph.xml`and after that declare the fragment:
Copy code
<fragment
        android:id="@+id/characters_favorites_fragment"
        android:name="com.vmadalin.dynamicfeatures.charactersfavorites.ui.favorite.CharactersFavoriteFragment"
        android:label="Favorites">
        <action
            android:id="@+id/action_characterFavoriteFragment_to_character_detail_fragment"
            app:destination="@+id/character_detail_fragment"
          />
    </fragment>
    <fragment
        android:id="@+id/character_detail_fragment"
        android:name="com.vmadalin.dynamicfeatures.characterslist.ui.detail.CharacterDetailFragment">
        <argument
            android:name="character_id"
            app:argType="long" />
    </fragment>
And also add the property event click on favorite character list.