Abort test on super method call - java

I've got the following method
public void myMethod(final MyObject myObject) {
if (myObject.isDownload()) {
// Do something
} else {
super.myMethod();
}
}
I want to verify now in a JUnit test, that the super implementation has been called.
I also want to abort the test, if the super call has been performed, since the underlying implementation is very complicated and hard to test respectively mock.
I'm using Mockito as a mocking framework.

That sounds like a perfect use case for a mocking framework. Just mock your implementation of super in a way that it does nothing on a call to myMethod(). Verify that myMethod() was called on your mock in the unit test.
You could give Mockito a try. But there are several other good mocking frameworks for Java.

Related

How to mock a function call in java

I am new to Unit testing and trying to figure out the different implementations of testing. I m trying to figure out how to mock a particular function call. I came across Mock Spy but didn't quite understand how it's been used. Can someone tell me how mocking is done in such cases...
Class ABC {
void display(String name, int id){
validateName(name);
validateId(id);
}
}
Class TestIt{
#Test
void testValidation(){
//how to mock validateName function call and test only validateId ?
ABC obj=new ABC();
obj.display("abc",2);
}
}
Some mocking frameworks allow partial mocks (most of the mocked class is actuall the real thing, just some methods are mocked). If your example is anywhere near the real code, I would not test the two methods separately. If one of these methods do something that is not wanted in a test, like accessing an external service (DB, webservice, filesystem), the I would encapsulate that functionality into an adapater class and inject it into ABC. Then you can mock the adapter.

Mocking a non-abstract method of an abstract class

I am trying to unit-test a class that extends an abstract base class.
Here are the "similar classes" for illustration purposes:
public abstract class MyAbstractBaseClass {
#Autowired
private WaterFilter waterFilter;
protected List<String> filterComponents(List<String> allComponents) {
return waterFilter.filter(allComponents);
}
}
public class MyDerivedClass extends MyAbstractBaseClass {
public List<String> filterWater(List<String> allWaterComponents) {
List<String> filteredComponents = this.filterComponents(allWaterComponents); //calls abstract class's filterComponets()
filteredComponents.add("something-else");
return filteredComponents;
}
}
Here is the unit test I am trying:
#RunWith(EasyMockRunner.class)
public class MyDerivedClassTest {
#TestSubject
private MyDerivedClassTest SUT;
#Before
public void setup() {
SUT = new MyDerivedClassTest();
}
#Test
public void test filterWater_HappyCase() {
//I want to mock my abstract class's filterComponents() method
//I am trying this:
EasyMock.expect(SUT.filterComponents(getDummyComponents())).andReturn(getSomeComponents());
//What to replay here?
//EasyMock.replay(...)
List<String> actualResult = SUT.filterWater(getDummyComponents());
//assert something
//What to verify?
//EasyMock.verify(...)
}
}
When I run this test, I get
java.lang.NullPointerException
in MyAbstractBaseClass.filter(allComponents)
I understand that the autowired "waterFilter" is not getting initialized. But then, I just want to mock the "non-abstract" method of the abstract class in my unit test.
How should I go about this using EasyMock? Also, I don't know what to replay() and verify().
When you write an unit test, you test a object (generally, a method of it) and you may mock a object (generally, a method of it).
However, you should not unit test and mock the same object because in a some way, it seems not very natural : if you test a method of a class, the behavior of the tested class should stay as natural as possible and not fake its own methods.
Otherwise, we can wonder if the quality of the unit test is good.
Why ? Because it doesn't reflect the real behavior of the class that we would have at the runtime, but just some part of its behavior.
In a unit test, isolation is researched but behind it, the idea is to isolate your under test class only from the other classes and not an isolation of its own behavior.
Of course, you can try to mock a no-abstract method in the abstract class of your under tested class but the design and the quality of your test may become less good.
In your case, I imagine two reasons to mock the no-abstract method in the abstract class :
the waterFilter field dependency annoys you because it is not valued, so an exception (NullPointerException) is raised during the test.
You really want to mock the no abstract method in the abstract class because you have already unitary tested this method and you don't want to duplicate this test.
1) If your the problem is the waterFilter field dependency.
you should mock the waterFilter field. To mock a field, it must be accessible and modifiable. In your case, it's not straight because the field is private.
So, you have two ways to access to it to be able to mock it :
change your design to give the possibility to set the field from a public method or in the constructor of MyDerivedClass.
use reflection to set the field (use an API or do it yourself because it's not hard).
You don't need to do verify operations with EasyMock. Just mock the result returned by waterFilter.filter(allComponents) such as :
waterFilterMock.filter(mockedComponents)
In this way, the mock returns the value you have chosen and in your JUnit assertion, you are able to do the correct assertion for your method under test.
Just for information, you could use Mockito instead of EasyMock. It's more flexible and it offers more readable operations.
For example, you could do it with Mockito :
Mockito.when(waterFilterMock.filter()).thenReturn(mockedComponents);
As you can see, it is more readable.
2) If you problem is that you really want to mock the no-abstract method in the abstract class because you have already unitary tested it
You should modify your design and use composition instead of inheritance. You would have not MyAbstractBaseClass any longer but simply a dependency between two classes (the one has a field of the other). In this way, you could mock the filterComponents() method in a natural way.
Expectations has to be set on mocked resources.
In your case i think you should inject a mocked instance of WaterFilter.
And your expectation,replay and verify should be set on waterFilter object instance.
You can refer to the example provided in given below link.
http://www.tutorialspoint.com/easymock/easymock_junit_integration.htm

how to unit test methods with dependencies

I need to create some unit testing for my application but I am not sure how to proceed and I couldn't find anything of help online. What I want to know is how to test an app where there are many methods dependent on a few others.
e.g.
public class foo(){
public void doIt() {
boz();
bar();
biz.baz(); //from another class
}
public void bar(){
...
}
public int boz(){
...
}
}
so in a scenario like the one presented above one would think that unit testing the doIt method would be sufficient since it is going to fail anyway if something is wrong with the methods called inside it.
Although, I am not sure if we can consider this to be unit testing as this tests the functionality of more than just an entity. In addition, if the test on the doIt method fails it is going to be really hard to tell where the error occurred especially in a case with many dependencies - doesn't that defy the meaning of unit testing?
So far the only approach I have thought is to start by testing the dependencies first (i.e. bar boz baz) and then the doIt method. That way, if the test suite gets to doIt with no errors and fails means that there is something wrong with the code implemented inside that method and not inside its dependencies.
BUT, is this the right way of doing it?
To test doIt() method without having to invoke the real implementations of bar() and baz(), use a Spy in Mockito:
Mockito spy documentation
If bar() is really void, you can do something like this:
foo f = spy(new foo());
doNothing().when(foo).bar();
Better is if you can inject your dependencies (ex: biz) as mock objects and test your foo class directly.

Junit and Mockito: How to test whether a method calls a method?

I'm trying to wrap my head around mockito and was wondering how I would test if a method calls a method!
So here is class with its method inside it:
public class RegisterController {
public void regHandle(UserDataObject user1){
ValidateRegisterInputController validate = new ValidateRegisterInputController();
validate.validateInputHandle(user1); }
How would I test that regHandle(UserDataObject) calls validate.validateInputHandle(user1); ?
I'm sure this is a super simple test, but I really can't figure out how to test this.
There are various ways of writing a test for a method which instantiates some other class. I wrote about two of them in my article on the Mockito wiki, at http://code.google.com/p/mockito/wiki/MockingObjectCreation
Both the techniques that I describe involve refactoring your code to make it more testable.
You would create a mock of ValidateRegisterInputController and then pass it on construction, then you would do:
Mockito.verify(mock).validateInputHandle(user1).
I strongly suggest you do not do this type of testing though. Instead of that, ask yourself how can you write an unit test that checks that what you wanted to validate was valid.
for example, check that after calling regHandle user1.isValid() is equals to true.

Is it a right case for Mockito spy?

Let's say I have a class
class SomeClass
{
public void methodA()
{}
public void methodB()
{}
public void someMethod()
{
methodA();
methodB();
}
}
I would like to test behavior of someMethod() with Mockito.
The only way I could think of is using spy();
Something like
SomeClass someClass = spy(new SomeClass());
someClass.someMethod();
InOrder inOrder = inOrder(someClass);
inOrder.verify(someClass).methodA();
inOrder.verify(someClass).methodB();
I'm new to the mockito and documentation says
"Real spies should be used carefully and occasionally, for example when dealing with legacy code."
So maybe I'm missing something and there is better (right) way to verify that methodA and methodB were called without explicitly calling them in the test case.
Thanks.
Yes, spy() is fit for your purpose. The warning is due to the fact that real methods are invoked, and hence you can get unexpected results (for example - real money being withdrawn from a bank account)
If your code needs spy for unit testing - something wrong.
Spy is a first sign of a code smell.
You have two options to avoid it in your example:
You can avoid mocking one of the method and test the whole someMethod.
If methodA and methodB is really needs to be mocked - you can move them to seperate class etc.

Categories