Verifying that Mockito.when calls are still needed - java

Over time, our tests have collected a whole bunch of Mockito.when calls. I'd like to know if there some that aren't needed any more. I tried doing
Mockito.verify(Mockito.when(someMock.someCall().return("foo").getMock(), Mockito.atLeastOnce());
But get
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
Is there a way to accomplish this? I'd like to aspect in a way to check if these when()s are being used as there are far too many for a human to do by hand, so trying to get to figure out how to do this inline.
I could just duplicate the same call found in when() with a completely separate call to Mockito.verify(), but it is hard duplicate the when() call method and arguments call chain through aspects.

The built-in solution to the problem would be to use strict stubbing. There is an article over at Baelung explaining it.

Related

What exception to use to prevent a method from being called multiple times?

I have a method that should only be called once during an object's lifetime. In order to ensure that this is the case, the method sets a boolean flag in the Object to true so it can later check if this method has already run. I am currently throwing an IllegalArgumentException (with a descriptive message) if this method is called a second time during a single object's lifetime, but that doesn't feel quite right to me, since the problem is not actually with the arguments themselves. Is there a better exception to use than an IllegalArgumentException?
I chose not to use an assert statement in this case, because the class and method are both visible outside the package, so the problem may be caused by code outside of my package. Is that correct thinking?
Throw an IllegalStateException.
But since exceptions shouldn't be part of the ordinary control flow, you should add a companion method, which returns a boolean that indicates whether the next call to the method will be successful.
An example for such a companion method is Iterator#hasNext().
A well-designed API must not force its clients to use exceptions for
ordinary control flow. A class with a “state-dependent” method that
can be invoked only under certain unpredictable conditions should
generally have a separate “state-testing” method indicating whether it
is appropriate to invoke the state-dependent method. For example, the
Iterator interface has the state-dependent method next and the
corresponding state-testing method hasNext.1
1: from Effective Java, Chapter 9: Exceptions
What should worry you more than the specific exception type is the fact that you created a bad design here.
Good interfaces make it easy to do the right thing and hard to do the wrong thing.
Meaning: your current implementation makes it easy to call that method twice; respectively you now force your clients to always check if that method was already called.
So, instead of spending your time on the exception type: step back and figure how to dissect your one class into two classes for example. And find a nice so that calling that specific method gives you a different object to work on. Or check if you should rather use a state machine to solve this problem.

Calling Mockito.when multiple times on same object?

When trying to use Mockito with Spring, by creating the Mock object via a bean declaration...
<bean id="accountMapper" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.example.persistence.mybatis.mappers.AccountMapper" />
</bean>
...I found some strange behavior when calling Mockito.when multiple times without reseting the Mock object, for example:
Mockito.when(this.accountMapper.createBadGrammarException()).thenThrow(new BadSqlGrammarException("Bla", null, new SQLException()));
As soon as this code (the "Mockito.when") is called multiple time during the test (on the same mock), the tests fails with an error (BadSqlGrammerException even if this exception was what was actually expected - I do get a failure if I don't throw the exception, and throwing it manually works fine). Is this expected behavior? Mockito seems to suggest creating a new mock every time, which would mean creating the DAO for each method...?
What exactly happens when I call the Mockito.when method two times? How should the mock react? Replace the behavior? Ignore it? Unfortunately most searches only yield results for how to return different results for multiple calls to the method itself, but not what is to be expected for multiple calls to Mockito.when...
I'm simply trying to understand Mockito and best practices here, because going with something just because it SEEMS to works seems to be a bad idea...
One of the problems with Mockito.when is that the argument you pass to it is the expression that you're trying to stub. So when you use Mockito.when twice for the same method call, the second time you use it, you'll actually get the behaviour that you stubbed the first time.
I actually recommend NOT using Mockito.when. There are many traps that you can fall into when you use it - quite a few cases when you need some other syntax instead. The "safer" alternative syntax is the "do" family of Mockito methods.
doReturn(value).when(mock).method(arguments ...);
doThrow(exception).when(mock).method(arguments ...);
doAnswer(answer).when(mock).method(arguments ...);
So in your case, you want
doThrow(new BadSqlGrammarException(??, ??, ??)).when(accountMapper).createBadGrammarException();
If you are starting out with Mockito, then I recommend that you learn to use the "do" family. They're the only way to mock void methods, and the Mockito documentation specifically mentions that. But they can be used whenever Mockito.when can be used. So if you use the "do" family, you'll end up with more consistency in your tests, and less of a learning curve.
For more information about the cases when you must use the "do" family, see my answer on Forming Mockito "grammars"
The simple answer is:
when you write Mockito.when(object.fooMethod()).then() then fooMethod() is actually called.
Another point is that we can't observe it first time, because it called on mocked object. But when we write when for the second time then we have some behavior for fooMethod() (we set it previously, in your case it Exception).
To check this better you can spy object:
Bar spyBar = Mockito.spy(Bar.class)
when(spyBar.fooMethod()).then()...
and fooMethod() will be actually called.

JMockit equivelant to Mockito doNothing()

In Mockito if you want a void method to do nothing you can do this:
doNothing().when(_mockedClass).voidMethod();
Is there a way to do this with JMockit?
I can't seem to find anything about it. I've been trying to switch to JMockit but am having trouble finding documentation for some of the things we do with Mockito. I suspect they are all there in one form or another, just having trouble finding them, so figured I'd start asking one question at a time here and hope there are easy answers! Thanks!
Just like with Mockito, actually, if you want a method to do nothing, then simply don't record an expectation for it. Alternatively, you can record an expectation with no result, but there is really no need for that (or a point to it).
(This would only not be the case when using strict expectations (with new StrictExpectations() {{ ... }}), in which case all method invocations need to be accounted for.)

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.

JNI: How to get method signature for debugging purposes

Can I enumerate all native methods in java, those that have to be
implemented in c/c++ using JNI?
Can I enumerate native methods by
name (there could be multiple overloads with the same name)?
How can I retrieve method signature to be able to generate the method
signature used by JNI?
Is there a way to check if all native jni methods have been bound properly, instead of trying to call them and get java.lang.UnsatisfiedLinkError exceptions. Sometimes method signature changes on either side without properly updating java or c++ side and I'd like to add some debugging code to detect these issues and handle them (perhaps by generating proper method signature and printing it to the log so I can easily fix the code).
I prefer JNI solution, but if something can be done with help on java side then it's ok also.
If I use registerNatives and register methods that weren't declared in java then it fails and prints it to logcat:
E/dalvikvm( 1445): ERROR: couldn't find native method
E/dalvikvm( 1445): Requested: Lcom/bla/bla/bla/Test;.nativeTestXX:()Z
but I'd like to catch this error and handle it myself. Is it possible to do it?
EDIT:
In my JNI code I have a static nativeInit (as suggested in Android JNI tips) that registers all native methods. In that same function I'd like to verify that all native methods are properly bound. That is, I don't need to wait till some uninitialized method is called and the app exists. The problem that I have: there is a lot of jni code written at different times by different ppl and some methods simply became incorrect, but they are used only in some obscure conditions. The best way for me, I think, is to check that all native methods are bound to some c++ function. The other problem, is that part of JNI code uses binding by exporting all these Long_java_names where method signature changes on either side cannot be detected.
There is no call to check for "unbound" native methods. Using RegisterNatives to perform explicit registration ensures that all methods you register have a matching declaration in the Java sources, but there is no way to check for native-declared methods for which there is no implementation (other than calling it and catching the exception).
At the point where a method with a native implementation is called, if nothing has yet been registered then Dalvik will search through the various shared libraries to find a match. What it sounds like you want is a way to force this search and check the result without actually calling the method. There is no such thing.
There are various ways to generate lists of native-declared methods, either statically or at runtime, but you also need a way to determine if an implementation is available. You're better off in the long run having unit tests that exercise the code.

Categories

Resources