How to test protected method is called or not in Mockito - java

This is a base class:
public abstract class BaseClass
{
protected void demoMethod()
{
//to Do
}
}
I want to test whether demoMethd() in sub class is called or not using Mockito.
I tried with Mockito.verify but call goes to sub class method but i want to super method to be called.Is there any solution to test whether super.demoMethod() is called or not. Code is given as below:
public class SubClass extends BaseClass
{
#Override
protected void demoMethod()
{
if( true)
{
return;
}
super.demoMethod();
}
}

According to me we can not call to protected method in Test class so therefore the things which i wanted is not possible for this case.

Related

Testing concrete methods in abstract classes using subclasses

abstract class BaseClass{
private final Dependency dep;
BaseClass(final Dependency dep){
this.dep = dep;
}
abstract void toBeImplementedBySubclasses();
public int concreteMethod(){
//Do some processing
return any_integer;
}
}
class DerivedOne{
#Inject
DerivedOne(final Dependency dep){
super(dep);
}
public void toBeImplementedBySubclasses(){
//DO SOMETHING RELEVANT TO DERIVED ONE IMPLEMENTATION
}
}
class DerivedTwo{
#Inject
DerivedOne(final Dependency dep){
super(dep);
}
public void toBeImplementedBySubclasses(){
//DO SOMETHING RELEVANT TO DERIVED TWO IMPLEMENTATION
}
}
I want to test concrete methods in abstract class.
Is it ok if I test the concrete methods in base class in the unit test for any of the two derived classes, or is there any other way?
So, if write test for DerivedOne class, it will include test for all methods AND the concrete method of the base class as well.
I know there is a thing "Mockito.CALLS_REAL_METHODS", using which we can test abstract classes, but in my case my base class has some dependencies which I initalise/inject using super() insider constructor of my derived classes, so I cant be doing it using CALLS_REALS_METHODS
There are two options which immediately come to mind here.
Firstly, you could write an abstract test class, which handles testing these methods, and then the test classes for your concrete implementations do the rest. For example:
public abstract class YourAbstractClassTest {
protected abstract YourAbstractClass getInstance();
#Test
public void testThing() {
final YourAbstractClass instance = this.getInstance();
instance.callMethod();
Assertions.assertTrue(instance.someProperties());
}
}
Alongside:
public class ConcreteSubclassTest extends YourAbstractClassTest {
private final ConcreteSubclass instance = new ConcreteSubclass();
#Override
protected YourAbstractClass getInstance() {
return this.instance;
}
#Test
public void moreTesting() {
this.instance.implementationSpecificMethod();
}
}
You could also create a dummy subclass in a test class for it:
public class AbstractClassTest {
private final AbstractClass instance = new AbstractClass() {
#Override
public void abstractMethod() {
throw new UnsupportedOperationException();
}
}
#Test
public void testThing() {
this.instance.concreteMethod();
// Just make sure this doesn't ever go near the
// methods you dummied up above...
}
}

How to Mock or Stub a protected method from abstract parent while testing a public method in child with both in different packages

I have legacy code that I can't change but I need to cover with a JUnit test. I've been trying out various Mockito and PowerMockito usages to no avail.
Abstract Parent
package com.parent;
public abstract class Parent {
public Parent() {
}
protected void badMethod() {
//code
}
// public methods
}
Public Child
package com.child;
public class Child extends Parent {
public void methodToTest() {
//code
badMethod();
//code
}
}
The code that I need to test comes after the call to badMethod(). Is there a way to stub, mock, or bypass the badMethod() call? There isn't an #Override for badMethod() in the child class.
The badMethod() call attempts to establish a database connection, as well as making calls to other services. I don't need any of this for the code that I am actually testing.
You can extend the class Child in your test and "disable" the badMethod in the new class.
public class YourTest {
#Test
public void testSomething() {
Child child = new ChildWithDisabledBadMethod();
child.methodToTest();
//put your assertions here
}
private static class ChildWithDisabledBadMethod extends Child {
protected void badMethod() {
}
}
}

How to block call overridden method from Child

For example I have two classes.
public class PActivity {
...
#Override
public boolean OnEventSocket(PMSocketEvent a_iEvent)
...
handled = OnEventSocket(...);
}
}
Second class:
public class PMenu extends PActivity {
#Override
public boolean OnEventSocket(PMSocketEvent a_iEvent)
{
...
}
}
How can I block the calling method from the second class?
Sometimes I want call the method OnEventSocket from the base class.
I have many classes like PMenu, so I have to make the change in PActivity
I would use a kind of template method pattern.
Essentially, rather than have an overridable public method, you override a protected method which is called by the public method. This allows you to do whatever checks you need to before invoking the overridden method.
public class PActivity {
...
public final boolean onEventSocket(args)
{
if (method_should_be_called)
{
eventSocketImpl(args);
}
}
protected boolean eventSocketImpl(args)
{
// default behaviour
}
}
public class PMenu extends PActivity {
#Override
protected boolean eventSocketImpl(args)
{
// overridden behaviour
}
}
You should be able to make this work without changing any of your PMenu implementations, with two drawbacks:
You will have a public method which should be protected
You will have to keep the current method names as they are, which may be confusing.

Mockito - Mock base implementation while testing derived class implementation of same method

I am using Mockito for some unit testing. I have the following classes:
public class Base {
public void say() {
System.out.println("Base"); // some work in the base class
}
}
public class Derived extends Base {
#Override
public void say() {
super.say(); // do the base class work
System.out.println("Derived"); // some additional work in the derived class
}
}
Now I want to test the Derived class's say() method while mocking the base say() method. I followed the suggestion here: Mockito How to mock only the call of a method of the superclass and I now have.
public class DerivedTest {
#Test
public void testSay() {
Derived obj = Mockito.spy(new Derived());
Mockito.doNothing().when((Base)obj).say();
obj.say();
// assert only "Derived" was output
}
}
But this doesn't work as it mocks both the base and the derived class implementation. I want to test just the extra logic in the derived class.
How can I do this.
Update: My solution
Since I couldn't change the base class as suggested, I modified my derived class to extract all the extra logic in a a separate method and just tested that method.
public class Derived extends Base {
#Override
public void say() {
super.say(); // do the base class work
doAdditionalWork(); // some additional work in the derived class
}
void doAdditionalWork() {
System.out.println("Derived");
}
}
public class DerivedTest {
#Test
public void testDoAdditionalWork() {
Derived obj = new Derived();
obj.doAdditionalWork();
// assert only "Derived" was output
}
}
This means that I am still not testing the derived say() method but given that the logic there is quite simple now, I hope I can be excused for this. The other downside is that I can't have a visibility stricter than package-private for the doAdditionalWork() method.
When you spy an object, you completely replace the implementation of the method(s) which you've defined a mock behavior for. So, as you noted in the question, this would not work.
One trick around this is to extract an additionalBehavior() method, and test it only, without spying or mocking:
public class Base {
public void say() {
System.out.println("Base"); // some work in the base class
additionalBehavior();
}
protected void additionalBehavior() {
// No implementation. Alternatively - make it abstract
}
}
public class Derived extends Base {
#Override
protected void additionalBehavior() {
System.out.println("Derived"); // some additional work in the derived class
}
}
public class DerivedTest {
#Test
public void testAdditionalBehavior() {
Derived obj = new Derived();
obj.additioanlBehavior();
// assert that "Derived" was the output
}
}

Call super class method automatically

Consider the following class
class A{
public void init(){
//do this first;
}
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
#Override
public void init()
{
super.init();
//do new stuff.
//I do not want to call atEnd() method here...
}
}
I have several B1, B2,... Bn child classes which are already developed. All of them extend class A. If I want to add a new functionality in all of them, the best place to do so is define that in a method within class A. But the condition is that the method should always get called automatically just before the init() method of child class ends.
One basic way to do so is to again add atEnd() method call at end of init() method of child classes. But is there any other way to do this smartly ??
One way to do this is by making init() final and delegating its operation to a second, overridable, method:
abstract class A {
public final void init() {
// insert prologue here
initImpl();
// insert epilogue here
}
protected abstract void initImpl();
}
class B extends A {
protected void initImpl() {
// ...
}
}
Whenever anyone calls init(), the prologue and epilogue are executed automatically, and the derived classes don't have to do a thing.
Another thought would be to weave in an aspect. Add before and after advice to a pointcut.
Make init() final, and provide a separate method for people to override that init() calls in the middle:
class A{
public final void init(){
//do this first;
}
protected void initCore() { }
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
#Override
protected void initCore()
{
//do new stuff.
}
}
The other answers are reasonable workarounds but to address the exact question: no, there is no way to do this automatically. You must explicitly call super.method().

Categories

Resources