I figured why not make all members of the RestServiceImpl private (some are package-private just for ease of testing, seems lazy) and remove the package-private helper method RestServiceImpl.addSupportedSearchHandler(SearchHandler) (which is only used for testing)
and mock the static Context.getRegisteredComponents(SearchHandler.class) with powermock. Which is the actual thing we want to control in our tests.
Now powermock was excluded from the openmrs-test dependency. Is that simply because it wasnt needed until now?
Excluding Powermock helps write better code by having to eliminate static calls and inject dependencies properly Also Powermock is sometimes causing trouble with our custom module classloading in tests (sorry I don’t have an example at hand to support that).
If you write new code, which doesn’t depend on any methods calling Context, it is better to inject dependencies properly (via a constructor or fields annotated with @Autowired) and test with mockito.
Exposing private methods as package-private is not the best approach for testing, but sometimes it’s a fast enough workaround to test them. It’s very unlikely you will call package-private methods in production by mistake. Calling by reflection in my opinion is worse as it makes the codebase harder to refactor.
The ideal solution for RESTWS-610 would be to refactor the class by extracting the logic to a separate class with public methods, which can be tested properly, without workarounds. It can be done easily, but I guess I didn’t look back when writing it the first time
I would really like to clean this up because its hard to add [RESTWS-613] - OpenMRS Issues
with the current state of affairs. And I agree, PowerMock can be a pain.
If you want to practice refactoring I would also move the whole SearchHandler logic out of RestServiceImpl to a new SearchHandlerMatcher class. It’s a bit more over what you need though