Skip to the content.

Catadioptre

Easily work with private members when testing in Java and Kotlin

Catadioptre is a lightweight library to work with private and protected members in Java and Kotlin using reflection and generated “proxies” methods.

With Catadioptre, you can:

Catadioptre supports variable, optional and named arguments in functions as well as suspend functions for Kotlin.

Should I really test my private methods?

Yes and no. A private methods is always part of the implementation of a bigger unit. Best practices encourage to test the feature, not the implementation. Therefore, conventions consist in testing the implementation of a private method through the public ones.

But let’s be honest. Often enough, this makes the testing of the feature more complex: you have to provide all the inputs combinations for all the use-cases to cover all the decision branches and use cases.

So, what are the options?

The first solution is a commonly used practice, but has a serious drawback: it exposes private pieces of code, (potentially) strength the coupling and reduces the consistency of your code. The second solution requires complex logic to access the private units. That’s where Catadioptre helps you.

Why using reflection and not byte-code manipulation?

To make private members accessible outside a class and generate “proxy” methods for it, we could have used code generation and manipulation libraries like the excellent ByteBuddy.

But this would have implied to:

Considering all those impacts, we preferred to apply the following strategy:

Why the name Catadioptre?

As describe just above, Catadioptre is using reflection to serve its purpose and in French, a “catadioptre” is a reflector you generally use on bicycles or road security equipments.

How to use Catadioptre?

In order to provide the best experience possible with your language of choice, we created two sets of utils, that provide equivalent features but in an idiomatic way.

You can discover how to use Catadioptre for Java or for Kotlin.

You will also find examples in the GitHub repository for both languages, using Gradle and Maven.

Catadioptre, mocks, stubs and spies

The generated functions and methods are just “facilities” to access to the private and protected members of a class in your tests. Hence, they are not used by the main code and are not relevant to mock, stub or spy your instances.

We encourage you to evaluate the absolute necessity to stub or verify a protected or private method in your tests and use a mocking library that supports such feature, like mockk for Kotlin

Visibility of classes to generate code

The visibility of the generated code is constrained by the one of the class declaring the testable members.

Classes with a visibility less than package-protected are not supported.

WARNING: When generating the proxies for Kotlin with Maven, internal classes are not supported. There is no known issue with Gradle.

Further currently known limitations

We are still in the development phase and improving the library as fast as we can. Here are known limitations:

We are heavily working to remove those limitations and improve your experience as much as possible.