Where must the argument be checked - java

In my java code I need to call one method inside the other. The argument passed to suspendUserTestList must not be null. So the very simple question is where I must to check for null case: before passing the value or inside the second method?
Here are my methods:
public String suspendTest(Integer locationId, Integer userId) {
testManager.suspendUserTestList(userTestList, SUSPENDED_TEST_FREQUENCY, usersTestsSuspenSession);
}
public void suspendUserTestList(List<UserTest> userTestList, Integer frequency, Session session) throws MonitorUsException {
if (userTestList == null) {
throw new MonitorUsException("Error");
}
}

Short answer will be Depends.
Long answer is .......
After looking at your method implementation, you are throwing the exception if it is null. So you have to call the method before checking to receive that exception.
If you check before calling the method, you won't receive any exception and it just skip the call to that method and proceeds further.
If you are fine with not calling even if it is null, check for null and then only call the method.

It's definitely a good idea to check the inputs of every method. So if your suspendUserTestList() method expects a non-null parameter, it should check that the parameter is indeed non-null before using it.
It makes your method more self-contained and less dependent on its calling environment. It's also easy to read and to test in isolation.
Whether you then also check in the caller is not so straightforward to answer, it depends on a lot of factors. I'd go with whatever looks cleaner.

Generally speaking
Generally, you want to check for null where you actually use the object's methods or properties.
However if the calling method knows that the called method will not check for null (when you use a library for instance, you have no control of how the object you give will be used, but by inspecting the code you may see that no null check is made), then you have to either check for null or catch NullPointerExceptions.
In any case, you must make sure to catch the possible NullPointerExceptions in a given layer of your application (for instance a level where you can provide the information to the user, if there is a UI).
Particular case
In your own particular case, your two methods are public. Because both can be called from outside, you have to make sure that the null check is made at the lowest level (suspendUserTestList), because you may start to call the suspendUserTestList method from other places in your code. By putting the null check in suspendUserTestList, you make sure that all other possible future calls to this method will have the same null check logic.

There is no fixed rule, both places can be valid. Common sense is to do it in the called method so you write the logic ones and not in all places where you use the method. Probably throw an IllegalArgumentException to not add new types for a common case.

It's definitely ok to check inside the public method (it's called "precondition"). As for checking before the call, it depends how you are using this userTestList field. Probably it was initialized in the constructor (like userTestList = new ArrayList<>()) and never reassigned. Then no need to check it anywhere (better to declare it as final). On the other hand it can be passed in some setter like this:
public void setUserTestList(List<UserTest> list) {
this.userTestList = list;
}
In this case it's much better to add one more check in the setter. In any case it's better to do the checks as early as possible.

Related

What is the best approach to check null when object is passed into several layers

Say I have a method which has the following signature.
public void processData(Map<String,String> map)
Now say this method iterates through a list and calls the below method on each of the item in the list, passing the map it has.
public void handle(Map<String,String> map)
Now I have checked for null in processData method. If its null it doesn't proceed from there, throwing a custom exception. But should I validate the map for null inside handle method too? Because its already validated in processData method. If its null handle method won't be called. I'm having this doubt because handle method has public visibility. I cannot have it as protected or default as both these methods are in classes of different packages. Any advice would be much appreciated.
This is an interesting question. I don't have a unique solution to this but here a few options:
You can indeed check for null in both functions. It won't slow down the execution and it is not bad practice. But indeed, if you have a cascade of 10 or 20 sub-functions, having so many checks might seem annoying.
You can leave it there without a check if you are sure it won't be called anywhere else, but that's not always satisfying.
You can add a method that throws the right exception if the map is null, this way instead of re-writing a check everywhere, you just have to call the same simple method. I would put such a method in one of your exception classes.
public static void checkMapNull(Map<String> map){ // throw exception if map is null }
public static void handle(Map<String> map) { checkMapNull(map); //dostuff }
Another interesting pattern consists in using a key to access your methods. I will go through this last one in details since I find it to be a quite interesting way to solve your issue. Start by creating a public class with a package-private constructor in the package that is supposed to handle the map. Then modify your handle method so that it needs a key as parameter: now only classes that can access the static key are able to call the handle method
// Key class - first package
public class Key {
private Key(){}
static Key key;
}
// Map handler class - second package
// Only the first package has a key to call handle!
public void handle(Map<String> map, Key key){ //dostuff }
In your case I would go for either the third or second option. But the key pattern in java can be extremely useful in some cases as it allows to mock the friend behavior from c++.
If you have a public method, then you have an API with a contract.
If the contract is that nulls are handled specially, then you should code that behaviour.
If the contract doesn't specify how nulls are handled, throwing an NPE (either explicitly or naturally), is acceptable (I would chose this option).
If the method should not be called by anyone, change it's visibility (saying "it's not my code" is not a reason not to do this).

Testing a method which calls private void method inside using mockito

I want to test a method which internally calls a void method.
Below is the code
public String process(MKSConnectionParams mksConnectionParam, IProgressMonitor progressMonitor) throws Exception {
if (null != progressMonitor) {
progressMonitor.beginTask("Starting the creation of report", 100);
}
if (null == mksConnectionParam) {
initialize(MksLibFactory.getDefault());
}
else {
initialize(mksConnectionParam, MksLibFactory.getDefault());
}
--------------
}
public void initialize(MKSConnectionParams mksConnectionParam, IMksLibrary mksLibDefault) throws Exception {
paramMKSConnectionParams = mksConnectionParam;
GlobalConstants.hostName = paramMKSConnectionParams.hostname;
GlobalConstants.port = String.valueOf(paramMKSConnectionParams.port);
try {
localISi = mksLibDefault.getSi(paramMKSConnectionParams);
localIIm = mksLibDefault.getIm(paramMKSConnectionParams);
}
catch (MksLibException | AuthenticationError e) {
throw e;
}
ProjectInfo prjInfo = localISi.getProjectInfo(pathToPj);
projRevCmd = prjInfo.getConfigPath().getConfigPath() + "#b=" + projectRevision;
}
I am writing mockito test case for process() method. Testing is getting failed when initialize(mksConnectionParam, MksLibFactory.getDefault()) is called. It is because in the process we are calling real mks connection and I am passing dummy user name and password.
We aren't able to mock this initialize method. Is there any way to do this?
Small pseudocode would be of great help.
Earlier I had initialize method as private. Would changing it to public make any difference?
There are several ways to test this scenario, and different people would advocate different approaches, mostly based on personal preference.
Notice that testing this, will require changes in the code of the class you're testing (I believe you neglected to mention its name). There is one exception, and that's if you're using PowerMock. I won't go into the details here, but you find out more on how to incorporate it into your mockito code here.
Back to regular testing methods, the problem is that you're using the real IMksLibrary instead of a mock, and that's because you obtain a reference to it inside the process method. Here are a few method that you might want to consider:
Change the signature of the process method to receive the reference to the IMksLibrary instance, so that the test code can supply a mock of it
Instead of creating the reference inside the process method inject a reference to the class, either by using some DI framework (e.g. Spring, Guice, CDI, etc.), or as a constructor parameter
Create a protected method called something like getIMjsLibraryInstance() in the class, that will return MksLibFactory.getDefault(), and use it instead of the explicit code (this is the Extract Method refactoring that can be automatically done by most IDEs for Java nowadays). In the test code, you need to create a subclass (this is why it's my least favorite method) which overrides this method and returns a mock, and test the subclass instead of the real class. Notice that this is the ONLY method that you should subclass
You might feel deterred from using the third method, since in effect, you're not really testing the class that you meant to test (but rather a subclass of it). I tend to agree that this has a bed smell to it. However, keep in mind, that unlike the other two methods, this will not require any changes to the clients of the class (this is a pretty strong argument in favor of it).
There are other methods that you can use, but they are pretty similar in nature to the first two methods, and they also require some changes in the code.
If you feel that any "regular" method of testing is not good enough (due to code changes or whatever other reason), you are welcomed to take a look at PowerMock, which will enable you to intercept the static method call that returns the IMksLibrary instance, and return a mock instead. A word of caution though. There are some serious coupling that happens when these type of solutions are used, so it is usually not highly recommended, unless you are really in a dire need.

Instance variable verification

Reading effective java, it mentions that we need to validate method parameters as a good practice, throw exceptions for public and assert for private methods. But, do we need to take any measure against instance variable.
EG: (dont take example as a use case, main question is Do I need to validate instance var or Not ?. Example was used only for explaining what i mean to ask. )
class Tree {
private Node root;
public doSomething() {
TreeNode node = root;
}
}
Now lets say root was never initialized and doSomething() was called directly, it would result in NullPtrException.
Do we need to guard against it ? If yes then how ? If no then why not ?
How about:
if (root == null) {
throw new SomethingException();
}
TreeNode node = root;
Simply put, just perform a null check on the root variable, and if it is null then execute code accordingly to fix that problem or throw a new exception for it.
The established practice to check method parameters can be generalized to check correct usage of a class. In the given example it is illegal to call method doSomething() when the instance variable root has not yet been initialized.
If you want a best practice rule, it is not to generally check instance variables, but to check that a certain usage protocol of a class is obeyed. (Unless the class is written in a way that no particular protocol needs to be followed, which is usually the better option.) This check will of course typically involve checking instance variables.
In contrast to throwing an IllegalArgumentException after a negative method parameter check, a protocol violation should lead to an IllegalStateException.
In the given example an IllegalStateException should be thrown, because that instance is not in a state where doSomething() may be called.
Move any validation code of instance variables to constructors and setters so you check it whenver it will be set or changed and throw any Exceptions if input is invalid BEFORE the change is made.
this keeps the instance variables in a valid state at all times for fully constructed objects so you don't have to sprinkle extra validation everywhere else.

Should exceptions be checked at lower level if higher level takes care of them

This is a quote from Effective java.
"Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. Sometimes you can do this by checking the validity of the higher-level method’s parameters before passing them on to lower layers."
Consider an object called "AccessControlContext actx" which is propogated from handler to lower levels. We can do a higher level check that "actx != null" but does it need to done in lower level again ?
Eg in psuedocode:
class RestServlet {
void verify Servlet(AccessControlContext actx) {
// check made at higher level according to effective java
if (actx == null) { throw exception; }
// do something
Verify.checkAccessControl(actx); // calling lower leve
// do something
}
}
class Verify {
static checkAccessControl(actx) {
// DO I NEED NULL POINTER CHECK HERE AGAIN ?
}
}
Although question is nested inside the comment, reiterating with elaboration.
A redundant check at lower level ensures defensive coding but - it is redundant.
It may be well spelled out in the javadocs that it does not accept null, but that does not solve the purpose of having a bug free code. Should we dedupe exception checks ?
NOTE: This was a random example. My question is not specific to this example. Its a broader question which seeks to understand how much to duplicate exceptions.
When it comes to validating parameters, in my opinion you can't do it too often. The way I'm used to working, parameters are validated in all layers of the code. If a method can't handle a null value (it would lead to a nullpointer for instance), it should be up to the method itself to make sure that the parameters passed aren't null. The same goes for methods where a bad parameter value would cause and exception further down in the layers.
The way I see it, if a bad parameter would cause an exception, it doesn't matter whether or not it is an exception thrown from a parameter validation at a high level or a parameter validation at low level, it is anyways better than the exception it would cause if there were no validation at all (or even worse, no exception and an erroneous execution.)
By letting each method be responsible for validating its input, even if it is just a passthrough-method, one can make sure that any new method calling an existing method will be prevented from passing along a bad parameter, since it would lead to a validation exception, no matter if the method being called is a high level or low level method.
So, in your example I would validate the input in both methods, with accompanying tests verifying that the validation behaves as it should. Input validation could also be as easy as a one-liner, check out the Validate class of apache commons lang: http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/Validate.html
For instance:
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.StringUtils;
public class Something {
public void doSomething(final Integer someInt, final String someString) {
Validate.notNull(someInt, "Can't proceed when someInt is null!");
Validate.isTrue(!StringUtils.isEmpty(someString, "Can't proceed when someString is null or empty!");
//do stuff
}
}
If the validation fails, an IllegalArgumentException with the message defined as the second parameter will be thrown. Tests could then look like this:
public class SomethingTest {
private Something something;
#Rule
public ExpectedException expectedException = ExpectedException.none();
#Before
public void setup() {
something = new Something();
}
#Test
public void doSomethingShouldFailIfSomeIntIsNull() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("someInt is null");
something.doSomething(null, "hello");
}
#Test
public void doSomethingShouldFailIfSomeStringIsEmpty() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("someString is null or empty");
something.doSomething(123, "");
}
//more tests..
}
I'm not sure that I'd be happy with this approach, what if checkAccessControl is called from many places? You have to rely on each caller doing the null check - it's not a safe way to proceed. I'd be putting the null check in to the checkAccessControl method, probably throwing IllegalArgumentException if a null was detected.
So, my broad approach would be, if your method relies on specific values being presented to it ( eg a parameter can't be null ), I would make it the responsibility of the method to validate it.
You can of course still ask the caller to validate the argument for you ( via javadocs for example ), but you can't enforce it.

EasyMock expectations with void methods

I'm using EasyMock to do some unit tests and I don't understand the usage of EasyMock.expectLastCall(). As you can see in my code below, I have an object with a method that returns void getting called in some other object's method. I would think that I have to make EasyMock expect that method call, but I tried commenting out the expectLastCall() invocation and it still works. Is it because I passed EasyMock.anyObject()) that it registered it as an expected call or is there something else going on?
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
The API doc for EasyMock says this about expectLastCall():
Returns the expectation setter for the last expected invocation in the current thread. This method is used for expected invocations on void methods.
This method returns you the handle of expectation through IExpectationSetters; which gives you ability to validate(assert) that your void method was called or not and related behaviors e.g.
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Detailed API of the IExpectationSetters is here.
In your example you are just getting the handle and not doing anything with it hence you don't see any impact of having or removing the statement. It's very same as you call some getter method or declare some variable and don't use it.
You only need EasyMock.expectLastCall(); when you need to further verify anything other than "That the method was called. (same as setting expectation)"
Say you want to verify how many times the method was called so you will add any of :
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Or say you want to throw an exception
EasyMock.expectLastCall().andThrow()
If you don't care then EasyMock.expectLastCall(); is not required and does not make any difference, your statement "obj.methodThatReturnsVoid(EasyMock.<String>anyObject());" is enough for setting up expectation.
You are missing EasyMock.verify(..)
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
// verify that your method was called
EasyMock.verify(obj);

Categories