Java `final` class and mockery

I am developing a software game in which players will have access to an abstract class and extend it to control the behavior of the robot. Since this is a software game, I try to protect my gaming infrastructure so that players do not mess around with the game, and not just the class that I give them; for this I do most of my final classes, but now I canโ€™t make fun of them in my unit tests (mockito + testNG).

So, I was wondering how can I get around this? there is a way, perhaps, to leave the classes not final for testing, and then somehow automatically โ€œ final -izeโ€ them at a later stage of the build cycle (I use maven in case it is relevant for the answer). I do not want to add another external library or change my mocking library.
If this is not possible, then the second question: does the final class really be safe? I saw several libraries that could remove the final classifier from bytecode, which makes me think that maybe then final useless if it can be removed from an already compiled class

+8
java maven unit-testing mockito mocking
source share
5 answers

Firstly, you cannot stop people from messing with your game by declaring things โ€œfinalโ€. There are analytic tricks and libraries for generating whole code that make it a little awkward to get past this.

So, play the final, and then you can use jmock or any other library that you like to make mocks.

+9
source share

Ultimately, you can try using automated refactoring tools such as Jackpot 3 or RefactoringNG . I have never tested them, but they are more than capable of doing what you want if you are going to refactor.

Another way would be to use Powermock, which allows you to scoff at the finals and statics (even tough I donโ€™t like mocking statics, as it assumes that something is wrong with your design).

+2
source share

You can always use delegation instead of inheritance.

 public interface Foo { // ... } public final class FooImpl implements Foo { // ... } public class MockFooImpl implements Foo { private FooImpl delegate; // ... } 

However, it is a bad idea to have abstract classes in your API. The interface will be better.

+1
source share

IMO, classes are marked final to make their objects immutable. If you want to control the behavior of the class, you put the methods in the class as private so that they cannot be overridden. If you leave them protected, then someone can extend your class, override these protected methods, and pass an instance of the extended class to your API, which expects your class object to be a parameter, thereby causing a behavior change. Thus, you would mark methods that you do not want to disclose as private.

You leave only extension points in terms of protected / public methods that can be overridden for user behavior by clients using these classes.

0
source share

Creating most final classes is good practice, since they are usually not intended to be extended by subclassing. All the books on API design that I know recommend recommending this ("Effective Java", "Practical API Design", "API Design for C ++"). This is useful for several reasons, including expressing the intent of an API developer, safely evolving the API, and preventing dead code (for example, a good IDE will determine when the final method does not use one of its parameters or never throws the thrown exception specified in the throws - this impossible for a non-final method).

Regarding the mocking of the mentioned classes, you just need to use the right tool for bullying, like JMockit (which I developed precisely because I wanted to write unit tests without sacrificing certain OO / API design practices).

0
source share

All Articles