'meaningfulPublicApi' is a *void method* and it *cannot* be stubbed with a *return value*!
Voids are usually stubbed with Throwables:
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. The method you are trying to stub is *overloaded*. Make sure you are calling the right overloaded version.
2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not verify/stub final methods.
3. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
What version of the product are you using? On what operating system?
I am working on Eclipse IDE
I get from your post that you are intending to stub out the private method doTheGamble() so that you can make it always return true for your test.
Might I suggest an alternative simpler approach that does not require the use of PowerMock. The part of the code that is troublesome for testing is the dependency on the Random object because we have no control over its behaviour. So for testing purposes this is the thing that we want to replace with our own Test Double. The way to do this is to wrap the java.util.Random class in our own domain construct and then use Dependency Injection. Here is how I might write the production code:
(We don't really even need the private method here at all, I could have just inlined the randomBoolean.generate() into the if predicate, but I've left it in to mirror the structure of your original Abc class)
There are advantages to this approach:
1) We have decoupled the java.util.Random library from our Gambler class which is good because we should always strive to write loosely coupled code. If we decide in the future that the java.util.Random library is just not doing it for us anymore we can write some other implementation of RandomBoolean and drop it in without having to alter the Gambler class.
2) We have encapsulated the task of generating random boolean values into its own class, thus simplifying the Gambler class. Remember, a function should do one thing only.
3) By having the Gambler class dependent on an interface, we can easily replace that dependency in our tests with a Test Double.
For this code I might write the following tests:
I've used inner classes here for convenience of demonstrating my approach but if you had other tests that are dealing with RandomBoolean's then you could just as well implement them as public classes in your test package so they can be reused.
For this test I have used nothing but jUnit. No need for elaborate mocking frameworks such as PowerMock.