I recently wrote a simple java app with Dagger 2 as a DI container and Gradle as a build system. I wanted to generate unit test coverage report for this app, so I used Jacoco.

In my build.gradle file I configured JaCoCo as follows:

1
2
3
4
5
6
7
8
9
10
plugins {
id 'jacoco'
}

jacocoTestReport {
reports {
xml.enabled = true
html.enabled = true
}
}

Now, I could type:

1
./gradlew test jacocoTestReport

Report was generated in build/reports/jacoco/ directory. I noticed that report includes Java code generated by Dagger during the compilation. I didn’t want to include it in the report because it doesn’t really make any sense to write unit tests for generated code.

I compiled project and browsed classes generated in build/classes/ directory. I’ve noticed that Dagger classes have similar patterns like:

  • DaggerApplicationComponent.class
  • ControllerModule_MemberInjector.class
  • ControllerModule_ProvideContextWrapperFactory.class
  • AccountController_Factory.class
  • and so on…

As you can see ApplicationComponent interface got its implementation with Dagger prefix and classes related to modules has postfixes like _MemberInjector, _Provide* and _Factory.

With this knowledge, I could improve my JaCoCo configuration and exclude classes, which match the Dagger pattern.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
jacocoTestReport {
reports {
xml.enabled = true
html.enabled = true
}

afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
excludes: [
'**/*_Provide*/**',
'**/*_Factory*/**',
'**/*_MembersInjector.class',
'**/*Dagger*'
])
})
}
}

Now, my report contains only code which was written by me and automatically generated classes are excluded.

You can apply similar trick while using other libraries, which generates Java code.