First off I'm very new to mockito.
I happened to overload a couple of methods in a legacy code base, that I was working on. However, as a result I had to change the test classes in order to make sure that the earlier test methods still called their original(intended) methods, one of the methods was passing in a null object earlier and as a result of the overloading, I had to do a cast ie.
Throwable(null) in the caller, and make a corresponding change in the verify event. So something like
ABCClass.logWarn(null,WarningString, description, (Throwable)null);
verify(event).setStatus(IsNull(Throwable.class));// this throws a compiler error asking me to create a method IsNull<Throwable>
Any thoughts on how I should fix this?
I would think this would work:
verify(event).setStatus((Throwable)null);
Related
I would like to share first what i know and probably think...
Binding -> Linking between method call and method defination.
It is said that early binding is the example of Method Overloading and
late binding is the example of Method Overriding
But, i was confused as we know that method is invoked after knowing the object type at run time and object is also created at run-time. So, when we write..
Parent obj = new Parent();
obj.method(int x) // one of the overloaded method
now, then in this case also method call should be determined at run-time?
but, they say method overloading is example of early binding? and it is determined already which method is to be called but then it will interfere with what i've said in the above line(which is object is created and runtime so, method invoking will also be decided at run time)
Now, I am sharing what I think..
the method overloading concept is only holded in class scope so it is definitely known that the method with integer parameter will be called.
but, as the inheritance enters and if that
method(int x)
is also overloaded then it comes to the kind of object is at run time.
even if it is not overridden and it calls like this
Parent obj = new Parent();
I think jvm still checks the method to invoke according to the class instantiated.
but I am confused that what I am thinking is true or not. I would also like to know internal working of this.
I'm studying the new Stream API for the OCP exam and I found something that I don't really understand. Here's my code:
void methodOne() {
this.compare(1, 2); // This works fine.
Stream.of(1,2,3)
.sorted(this::compare); // Compilation error.
}
static Integer compare(Integer s1, Integer s2) {
return 0;
}
Here I have a static method called compare and a non-static one called compare. If I call the compare method from the non-static method I get a compiler warning:
The method compare(Integer, Integer) from the type TestStream should be accessed in a static way
If I instead use a method reference to that same method in my stream, that compiler warning becomes a compiler error with the same message.
I know why I get the warning but I don't get why this warning becomes a compilation error if I use a method reference. I didn't find anything online either. Can someone explain it to me?
Accessing a static method via a reference was seen as a design error to this day AFAIK. You can even do:
YourClass c = null;
c.compare (...)
And that would work just fine (with a warning though).
When java-8 features where designed this was corrected, so the only way to access a static method (for a method reference) is via the class itself:
YourClass::compare
I know why I get the warning but I don't get why this warning becomes
a compilation error if I a method reference. I didn't find anything
online either. Can someone explain it to me?
It should have been a compilation error in both cases, but the earlier versions of Java tolerated it because the designers of the language didn't know better, and now for continued compatibility it is too late to change it.
However, method references are a newly constructed language syntax. When you're using the construction <object instance>::<method name>, then by definition the method you're trying to reference cannot be a static method since you're accessing it by specifying what object instance you want it applied to, which a static method is incapable to do.
Doing it right this time and rejecting invalid constructs that try to access static stuff through an instance, doesn't break any existing syntax of the language that may have been used somewhere by someone, albeit unwisely. So they did it right this time. Don't do invalid things, the compiler ought to reject them, and in that case it will.
It would also complicate parameters inference in case of overloaded methods, some static and some non-static. But it wouldn't be the first inference hell they would have to make do with.
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.
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.
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);