mockito: how to verify calls on real implementation? - java

I'd like to verify calls to a logger object, so that the real implementation is still called (so I can see the output during tests).
Something like
verify(logger).error(anyString())

you need to use spy to verify invocations on real objects.

Related

UnfinishedStubbingException when JUnit tests are ran in random order

The following test is one of several tests that fail when I run my tests in random order using this Maven command: mvn -Dsurefire.runOrder=random clean test
#Test
public void ShouldReturnCorrectAccountLoanSumForDebtRatioWhenRedemptionAmountIsNull(){
AccountVO account = mock(AccountVO.class);
CustomerGroupInformationVO group = mock(CustomerGroupInformationVO.class);
when(group.getCustomerIds()).thenReturn(Set.of("199406208123"));
when(account.getAccountOwners()).thenReturn(List.of((new AccountOwnerVO(null, "199406208123", null))));
when(account.getAmount()).thenReturn(BigDecimal.valueOf(500000));
when(account.getRedemptionAmount()).thenReturn(null);
assertEquals(BigDecimal.valueOf(500000), getAdjustedAccountLoanSumForDebtRatio(account, group, caseClientVO));
}
More specifically this is the line mentioned:
when(account.getAccountOwners()).thenReturn(List.of((new AccountOwnerVO(null, "199406208123", null))));
Any idea what is causing this and how I can fix it? When I run my tests normally using mvn clean install there are no issues at all. The reason I want it to work with a random order is that our build tool seems to use it and it can't build. Like I said it works fine locally.
Because Mockito works through side-effects stored in ThreadLocal variables, it is particularly subject to test pollution: If your tests fail when run in random order, it may be because some previous test left a mock in a state it wasn't expecting to be in. Also, Mockito stubbing relies on observing method calls in a specific order, which can cause odd exceptions if it can't observe the method calls (such as when they're final) or if you interact with a different mock while preparing a thenVerb argument.
One of your first lines of defense is to use validateMockitoUsage, which is meant to be run at the end of every test and confirms that no interaction with Mockito is left unfinished. You could put this in an #After method, but Mockito does so automatically if using MockitoJUnitRunner or MockitoRule. I'd recommend either of those latter options if possible, particularly MockitoRule.
This should help you confirm which test(s) are problematic. Once you're there, try these:
Double-check that you're not trying to mock final methods without Mockito's opt-in final support. If Mockito can't override your mock method, it won't be able to detect your stubbing calls in its expected order. If any of your methods are written in Kotlin, remember that unlike Java the methods are final unless declared open.
Your test doesn't seem to use Matchers, but if you do, make sure you use them for all arguments in a method if you use them for any argument in a method.
Be careful about calling real methods in the middle of stubbing. new AccountOwnerVO(...) shouldn't interact with mocks, but if it does, then Mockito might interpreted it as if your when call never got a thenReturn (when in reality it just hasn't gotten to it yet). Extracting your return value as a local variable is a reasonable step to try.

Replay like function in PowerMock-Mockito

Which method in PowerMock-Mockito java can be used to replay the class under test (like PowerMock.replay() followed by PowerMock.verify()) and verify whether the private methods (methods are part of class under test ) calls ?
You shouldn't be verifying private method calls, as they're implementation details. That PowerMock allows you to do so is no indication that you should.
Even if you do choose to mock private method calls, you could only access them from your system-under-test, which indicates that you're mocking the system under test: Don't mock the system under test. It's far too easy to accidentally verify that your mocking system works, not that your component actually does what it's supposed to.
Mockito doesn't have record-replay semantics, so you won't be able to access that functionality from PowerMock-Mockito. You'd need PowerMock's EasyMock syntax instead.

Mocking static void method and changing its behaviour

I have a static void method from a different class that is invoked along my code as some sort of logger. In order to automatically test the different use cases of my code I was thinking of checking the logs of the system created by such method.
What I thought is to mock that class and overwrite the behaviour of the method so that it outputs to System.err. Also, redirecting System.err as explained here so that I can easily verify the correct functioning of the code.
I do not know how to override the standard behaviour of the method so that it does something (printing to the stderr) instead of what it normally does (by not mocking it) or nothing (what I get my using when(...).thenReturn(...))
Mocking static method is not a good way to go, believe me.
Altough it is possible with for example PowerMock framework (it is going to replace class loader under the hood), but still it is discouraged.

What is the difference between full mocking and partial mocking?

I'm currently working with mocking with Mockito using jUnit and I've stumbled upon the Partial Mocking section where you use Mockito.spy to partially mock the object. I don't seem to understand this concept of partial mocking since I can't find a scenario why I should use it (since it's pretty similar to mocking in general).
Can anybody explain how partial mocking differs from the normal mocking? And if possible, kindly provide examples.
Thanks!
Partial mocking is where you take a class and ask it to behave as normal, except you want to override certain functionality.
This is useful for unit testing services who communicate with other parts of your application. By overriding the behaviour that would call the other part of your application you can test your service in isolation.
Another example would be when a component would communicate with a database driver. By mocking the part that would communicate with the driver, you can test that part of the application without having to have a database.
From the EasyMock 2.2 classextension documentation:
Sometimes you may need to mock only some methods of a class and keep
the normal behavior of others. This usually happens when you want to
test a method that calls some others in the same class. So you want to
keep the normal behavior of the tested method and mock the others.
I sometimes use this to mock (complicated or process intensive) private methods that are allready fully tested.
Partial mocking can be very handy, but I try to avoid it as much as possible.
Partial mocking:
Say you have a class which takes 10+ parameters for a constructor (this shouldn't ever happen but for this example lets say it does) it's a real chore to create that entire object. Frameworks like mockito let you just use the parts of the object you really want to test.
for example
#Mock BigClass big; //contains loads of attributes
...
when(big.getAttributeOneOfTwenty()).thenReturn(2); //these are static imports from mockito
I find it useful when I'm forced to work with APIs relying on inheritance from abstract classes and/or legacy code working with nonmockable static classes (one real life example - DAO).
Partial mocking (in sense of using the Spy facility from Mockito) allows you to mock calls to inherited methods in the first case, or wrap calls to static methods you are forced to use into normal methods that you can mock, verify etc.
Generally you should design and write code in such a way, that you won't need this (dependency injection, single responsibility per class etc). But from time to time it's useful.
A quick and rough example, to visualize the static API example:
class BigUglyStaticLegacyApi {
public static Foo someStaticMethodFetchingFoo() {...}
}
class Bar {
public void someMethodYouTest() {
Foo foo = getFoo();
//do something with Foo (a FooBar, for example :) )
}
/*this one you mock via spying - not the most elegant solution,
but it's better than nothing */
#VisibleForTesting
protected Foo getFoo() {
return BigUglyStaticLegacyApi.someStaticMethodFetchingFoo();
}
}
I use it the most to mock some methods in my CUT (Class Under Test) but not the method/s I'm actually unit testing. It is an important feature that should be used in unit testing with Mockito.

Mockito mock() and recording of invocation

I'm using Mockito in order to do some mocks/testing. My scenario is simple : I have a class mocked using mock() and I'm invoking this class (indirectly) for a large number of times (i.e. ~100k)
Mockito seems to hold some data for every invocation, and so I run out of memory at a certain point.
I'd like to tell mockito not to hold any data (I don't intend to call verify(), etc, I just don't care, for this specific tests, what reaches to that mock). I don't want to create new mocks with every invocation.
You can use Mockito.reset(mock), just be aware that after you call it, your mock will forget all stubbing as well as all interactions, so you would need to set it up again. Mockito's documentation on the method has these usage instructions:
List mock = mock(List.class);
when(mock.size()).thenReturn(10);
mock.add(1);
reset(mock);
//at this point the mock forgot any interactions & stubbing
They do also discourage use of this method, like the comments on your question do. Usually it means you could refactor your test to be more focused:
Instead of reset() please consider writing simple, small and focused test methods over lengthy, over-specified tests. First potential code smell is reset() in the middle of the test method. This probably means you're testing too much. Follow the whisper of your test methods: "Please keep us small & focused on single behavior". There are several threads about it on mockito mailing list.

Categories

Resources