j

    Jitendra

    1 week ago
    I have setup dagger in my project, but struggling with Unit testing any one have any good articles or GitHub repo that can help
    m

    mattinger

    3 days ago
    Take a look at the dagger testing page: https://dagger.dev/dev-guide/testing.html I’m not a big fan of component inheritance as they suggest (as it doesn’t work with anvil, which is a whole separate discussion). I prefer use interfaces for things like injection, accessors, subcomponent creators, etc… And then i develop my app in such a way that outside of the construction of your component (likely in Application.onCreate), nothing else in your app knows what actual component type is there. Just that it’s something that implements certain interfaces.
    interface MyInjectors {
       fun inject(activity: MyActivity)
    
    @Component(...)
    fun MyComponent: MyInjectors {
       ...
    }
    I then use this custom class to hold components and retrieve whatever registered component implements the requested interface. when i created the component, i register it with this registry.
    object ComponentRegistry {
        @PublishedApi
        @Suppress("ObjectPropertyNaming")
        internal val _components = mutableSetOf<Any>()
    
        fun add(component: Any) {
            _components.add(component)
        }
    
        fun remove(component: Any): Boolean =
            _components.remove(component)
    
        val size: Int
            get() = _components.size
    
        fun clear() = _components.clear()
    
        inline fun <reified T> hasComponent() =
            _components
                .filterIsInstance<T>()
                .isNotEmpty()
    
        inline fun <reified T> getOrNull(): T? =
            _components
                .filterIsInstance<T>()
                .singleOrNull()
    
        inline fun <reified T> get(): T =
            _components
                .filterIsInstance<T>()
                .single()
    
        inline fun <reified T> replace(component: Any) {
            getOrNull<T>()?.let { remove(it) }
            add(component)
        }
    }
    And at your injection point:
    ComponentRegistry.get<MyInjectors>().inject(this)
    If you follow this pattern, it becomes very easy to replace your regular app component with a completely different component when doing both unit tests and espresso tests.