https://kotlinlang.org logo
#dagger
Title
a

Amrita Chaturvedi

02/25/2021, 6:55 AM
Hi, Does anyone here have experience or relevant resources for mocking dagger related dependencies while unit testing in a multi-module clean architecture-based project? Kinda stuck with it here. 😅
a

allan.conda

02/25/2021, 7:10 AM
What are you stuck with?
a

Amrita Chaturvedi

02/25/2021, 7:22 AM
So I have created a testing app component, but I am unable to inject the classes in my test file.
a

allan.conda

02/25/2021, 7:23 AM
what kind of test are you writing?
a

Amrita Chaturvedi

02/25/2021, 7:24 AM
I am trying to test the ViewModels
a

allan.conda

02/25/2021, 7:26 AM
For unit tests just construct the class in test manually. See the last section here: https://dagger.dev/dev-guide/testing.html
☝️ 1
a

Amrita Chaturvedi

02/25/2021, 7:26 AM
But I have a lot of dependencies, it will be difficult to manually create each of them.
a

allan.conda

02/25/2021, 7:28 AM
Ok, I recommend read the whole article instead of just the last section.
It’s more difficult to write the dagger setup. You have to write tons of fakes, and mocks, anyway, if you want to test the ViewModel
And if you’re using Hilt, JVM tests aren’t supported yet
a

Amrita Chaturvedi

02/25/2021, 7:30 AM
I was actually following the Option 2 that is mentioned there, but despite the dependency graph for Test App Component was generated, it couldn’t be injected. I am not using Hilt, Just dagger android.
a

allan.conda

02/25/2021, 7:33 AM
Hmm, you mention multi-module project, are you trying to inject fakes or other shared test classes (like test data) from another module, or just using plain mockito?
Test classes can’t be shared across modules normally
a

Amrita Chaturvedi

02/25/2021, 7:34 AM
Not trying to fake other test classes as of now.
t

trevjones

02/26/2021, 12:37 AM
So I don't know why its not in the docs or not recommended or w/e but I usually just do a standalone component for a specific test, works great with dagger android because a subcomponent implementation is specific to the enclosing component. plus then the graph validation is only on the parts of the graph you need for the test.
Copy code
@Component(modules = [WhateverYouWantOrNeedModule::class])
interface TheTestComponent {
  val theViewModelToTest: SomeViewModel
  val somethingYouCheckToValidateOrConfigure: SomethingViewModelDependsOn
}
i use a similar pattern for UI tests too. works great with the activity or fragment scenario rules so you can validate an entire view stack in isolation with faked network calls etc...
if you are using just plain
jar
modules you can also use the test fixtures plugin and have your library module also provide fake versions of shared interfaces for things like data loading and such. then you are able to hopefully keep things like mockito out of your tests.
j

Jeremy

02/26/2021, 1:42 AM
Generally you shouldn't need to do anything w/ dagger/di in your unit tests, thats the point of DI
👌 2
If its espresso end to end test you can provide an alternate component in the relevant src variant dir and provide fakes for certain things like repository
If having trouble w/ testing due to "a lot of dependencies" might want to review classes to ensure seperation of concerns and/or use interfaces for the dependencies
a

Amrita Chaturvedi

03/03/2021, 9:14 AM
It took me a while, but I finally understood. Thank you! 🙌
❤️ 1