question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PowerMock and MockMaker: API change request.

See original GitHub issue

Hi guys,

I’ve taken a time for reviewing PowerMock code to find place where it use internal Mockito API. I’d like to discuss what could be done to avoid.

First think that I’d like to talk about it’s MockMaker. PowerMock uses it custom MockMaker, which it past was used only for two things:

  • cache a class create by CgLib
  • return fake InternalMockHandler for static mocks.

The first case is no more actual, because ByteBuddy uses current context ClassLoader, so MockClassLoader is used. But the second case still actual. But investigation shows that returning fake InternalMockHandler is required only for one case right now.

Method org.mockito.internal.exceptions.Reporter.noMoreInteractionsWanted(Invocation undesired, List<VerificationAwareInvocation> invocations) tries to safelyGetMockName(undesired.getMock()). Finally, call comes to org.mockito.internal.util.MockUtilisMock(Object mock). It tries to get MockHandler for mock, but it mock is static and it’s not a PowerMockMaker, then null is returned. I was surprised that having PowerMockMaker is required only for such thing. If speak, honestly, I don’t have any idea, how it can be fixed on Mockito site. Maybe you have any thoughts?

The second point, it’s a way how Mockito loads plugins. We had some discussion within #1006. Main point provided @podarsmarty (as for me main) that if there are two files org.mockito.plugins.MockMaker in class path, then order of loading plugins are unpredictable. Such undetermined behaviour could introduce some fluky bugs, when for example one plugin specified in project and other in dependency jar. And for example it works, but later author of dependency jar make refactoring and change package or something like this. As result other plugin is loaded by Mockito and tests start failed.

For PowerMock it is issue, because is has own MockMaker, which is required only if test runs with PowerMock. But, unfortunately, if PowerMock in class path it will be used always. If a developer wants to use mock-maker-inline to be able to mock final without PowerMock, then it was impossible until PowerMock 1.7.0, where I added ability to specify MockMaker to which PowerMockMaker delegates calls. As for me, it will be good to have ability to separate custom MockMaker and Mockito build-in MockMaker. So custom MockMaker could know which build-in MockMaker should be used to delegate call if its required.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:99 (53 by maintainers)

github_iconTop GitHub Comments

1reaction
thekingn0thingcommented, Jun 28, 2017

Thank you for working on this! I would love to see us getting to the conclusion - nice demonstration of 2 library owners working together to develop clean & flexible API 😃

Thank you for assisting me. I’m also really happy to see how we move. It’s a big win for community!

Can you address this issue by making sure Powermockito mocks have the mock type? Here we come to main reason why I asked “Creating settings object from other settings object (e.g. copy)”. I need ability to set mock type and mock name to already defined mock settings.

1reaction
mockitoguycommented, Jun 7, 2017

@thekingnothing, do you live in Krakow? I spent most of my adult life in Krakow 😉

Thank you for reaching out to us so that we can work together. That’s how this should be done - we design the APIs between open source components so that our users get higher quality products (e.g. products that don’t break on version upgrade 😃.

I’m also surprised that those are the only issues with using Mockito’s private API. Something tells me there is more. Let’s keep working on this an expose all integration points.

Method org.mockito.internal.exceptions.Reporter.noMoreInteractionsWanted(Invocation undesired, List<VerificationAwareInvocation> invocations) tries to safelyGetMockName(undesired.getMock()). Finally, call comes to org.mockito.internal.util.MockUtilisMock(Object mock). It tries to get MockHandler for mock, but it mock is static and it’s not a PowerMockMaker, then null is returned. I was surprised that having PowerMockMaker is required only for such thing. If speak, honestly, I don’t have any idea, how it can be fixed on Mockito site. Maybe you have any thoughts?

Multiple methods from Reporter class attempt to use ‘safelyGetMockName’. I assume you use ‘noMoreInteractionsWanted’ as an example. Getting mock name is only used to make verification errors cleaner. It’s not a critical feature, without it the errors are still decent.

To get started, I suggest to hack Mockito code and return empty String if getting mock name throws an exception. This way you can push forward and identify other contention points. Once we get full picture we can design public API that will solve all use cases cases for integration with PowerMock.

The second point, it’s a way how Mockito loads plugins. We had some discussion within #1006. Main point provided @podarsmarty (as for me main) that if there are two files org.mockito.plugins.MockMaker in class path, then order of loading plugins are unpredictable. Such undetermined behaviour could introduce some fluky bugs, when for example one plugin specified in project and other in dependency jar. And for example it works, but later author of dependency jar make refactoring and change package or something like this. As result other plugin is loaded by Mockito and tests start failed.

I totally agree that random order of loading plugins is undesired. We don’t have a clean way of solving this problem at the moment. It needs more brainstorming. Ideas are welcome 😃

For PowerMock it is issue, because is has own MockMaker, which is required only if test runs with PowerMock. But, unfortunately, if PowerMock in class path it will be used always. If a developer wants to use mock-maker-inline to be able to mock final without PowerMock, then it was impossible until PowerMock 1.7.0, where I added ability to specify MockMaker to which PowerMockMaker delegates calls. As for me, it will be good to have ability to separate custom MockMaker and Mockito build-in MockMaker. So custom MockMaker could know which build-in MockMaker should be used to delegate call if its required.

This is an interesting use case. Let me understand it: an author of custom MockMaker would like to have access to default Mockito MockMaker so that she can delegate some invocations to it? In Mockito we can introduce public API to expose the default mock maker (or means to obtain the default mock maker).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mockito 2.x over PowerMock Migration: Top 10 Tips and Tricks
In the beginning when just changing Mockito version to 2.x in your build.gradle file, you may find more ... at org.powermock.api.mockito.internal.mockmaker.
Read more >
Use org.powermock.api.mockito.mockmaker ... - LambdaTest
Learn how to use MockMakerLoader class in org.powermock.api.mockito.mockmaker package for your next JUnit project with LambdaTest Automation Testing Advisor ...
Read more >
Mockito Mock Static Method - PowerMock - DigitalOcean
We need following PowerMock dependencies for mocking static methods in Mockito. powermock-api-mockito2 : This is the core PowerMock dependency ...
Read more >
Mockito (Mockito 4.9.0 API) - javadoc.io
53. Specifying mock maker for individual mocks (Since 4.8.0) ... Mockito follows semantic versioning and contains breaking changes only on major version ...
Read more >
Mocking method calls using power mockito - org.powermock ...
mock-maker -inline. EDIT 2: Since Mockito 3.4.0 its now possible to mock static method too: try (MockedStatic mocked = mockStatic(Base64.class)) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found