Kotlin and new ActivityTestRule The Rule must be public
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
The rule must be public error usually appears because JUnit 4 is inspecting Kotlin test code through Java reflection. The Kotlin property may look correct in source code, but the generated Java-visible shape is what matters, so the fix is usually to expose the rule through @get:Rule or @JvmField in the form JUnit expects.
Why Kotlin and JUnit Disagree
In Java, a JUnit rule is commonly declared as a public field. In Kotlin, a property is not automatically the same thing as a plain Java field. It usually becomes a private backing field plus public accessors.
That difference matters because JUnit rule discovery is not looking at Kotlin semantics. It is looking at Java reflection targets.
So code that compiles cleanly can still fail at runtime because JUnit does not see the rule in the expected public form.
The Usual Kotlin Fix: @get:Rule
For Kotlin tests, the most common pattern is to annotate the generated getter explicitly.
This works because JUnit can see a public getter carrying the rule annotation.
Field-Based Alternative: @JvmField
Older examples often use a field-style declaration instead. In that pattern, @JvmField removes the accessor indirection so JUnit sees a Java field.
This style is still valid. The key point is that @get:Rule and @Rule @JvmField are two different ways to give JUnit a Java-visible rule.
ActivityTestRule Versus ActivityScenarioRule
If you are already touching legacy instrumentation tests, it is worth asking whether ActivityTestRule should still be used at all. In many AndroidX codebases, ActivityScenarioRule is the more modern choice.
Legacy style:
Modern style:
The visibility fix is one issue. Modernizing the rule type may be another.
Check the Test Dependencies Too
If the syntax looks right and the error still persists, inspect the AndroidX test dependencies. Mixed old support-test libraries and AndroidX libraries can produce confusing results that look like a Kotlin visibility problem.
Keep the runner, rules, and integration libraries aligned.
A Safe Fix Sequence
When inheriting a failing legacy suite, change one class first instead of rewriting every rule declaration at once:
- convert one failing rule to
@get:Rule - rerun the instrumentation tests
- if needed, inspect the dependency stack
- only then migrate old
ActivityTestRuleusages more broadly
That incremental approach makes it much easier to tell whether the real cause was annotation targeting, bytecode shape, or stale AndroidX test dependencies.
Common Pitfalls
- Writing a normal Kotlin property with
@Ruleand assuming JUnit will treat it exactly like a public Java field. - Assuming
@JvmFieldis always required; it depends on whether you are using a field-based or getter-based pattern. - Fixing the annotation target while leaving a mixed or outdated Android test dependency stack in place.
- Modernizing every legacy rule in one large sweep instead of fixing one failing pattern at a time.
- Treating the error as a Kotlin visibility bug only, when it is really about Java reflection shape.
Summary
- The
rule must be publicerror is usually about how Kotlin exposes the rule to JUnit 4 through Java reflection. - '
@get:Ruleis the most common Kotlin-friendly pattern.' - '
@Rule @JvmFieldis the field-based alternative, especially in older code.' - '
ActivityScenarioRuleis often a better modern choice thanActivityTestRule.' - If the syntax is correct and the error remains, inspect the test dependency stack next.
Related reading
- Kotlin async await with limited parallelism
- Kotlin Compiler in Android Application Connection refused to host 127.0.0.1
- Kotlin Interface ... does not have constructors
- Kotlin Spring Boot ConfigurationProperties
- Launch iOS simulator from Xcode and getting a black screen, followed by Xcode hanging and unable to stop tasks
- Load different application.yml in SpringBoot Test
- Kotlin Ternary Conditional Operator
- Label Alignment in iOS 6 - UITextAlignment deprecated
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.