0

So, my problem is like this? I have private method in which I am passing the variable a and these are the conditions for the boolean variable to be true. I am having a class B having getB(), class C having getC() methods, interface D having getD() method with return type as long. I am having another method (static boolean isE()) in which I am passing a local variable f and calling method getG() from a different class H.

How do I mock these values for unit testing using Mockito so that my boolean variable check becomes true.

boolean check = a != null
                && a.getB().getC().getD() >= 0
                && !isE(f.getG()))
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Neha Khare
  • 1
  • 1
  • 2
  • Are you sure that mocking is the right thing™ to do here? Usually mocking should be reserved for calls to external dependencies (database, webservice, network, etc.), not for overriding behavior of private methods. Have a look at the _strtategy pattern_, maybe this already helps in your case? – knittl Aug 04 '20 at 05:42

3 Answers3

0

you have to mock on an external call. if you are writing tests for class A..mock all the instances of Class B or Class C..like:

when(instance_of_class_b.someMethodOnClassB()).then(return true or false).

Mocking means mocking external calls from class.You cannot mock private calls within the same class,no meanning to that.

Check on Mockito library for more info

asgher
  • 46
  • 5
0

Firstly, you cannot test private methods with JUnit/Mockito out of the box.

Secondly, your naming is confusing: You say „B having getB()“ and then you call the parameter a (for a.getB()). B.getB() is supposed to return a C, not a B, since getC() is invoked on it then. And you say „C having getC()“ and also „nested methods“. Furthermore, D.getD() doesn't return an object of type D but a long. I adapted all this according to what I thought you intended.

If you make your method in your class under test non-private it works as follows:

Surrounding classes for demonstration

class B {
    C getC() {
        return null;
    }
}
class C {
    D getD() {
        return null;
    }
}
interface D {
    default long getLong() {
        return -1;
    }
}
class E extends G {
}
class F {
    G getG() {
        return new E();
    }
}
class G {
}

Class under test

import static java.lang.System.out;

class Clazz {

    static boolean isE( final Object o ) {
        return o instanceof E;
    }

    F f;

    boolean method( final B b, final String origin ) {
        out.printf( "---- %s%nb=%s%n", origin, b );
        out.printf( "long=%s, original: %s%nisE=%s, original: %s%n",
                b != null ? String.valueOf( b.getC().getD().getLong() ) : "<not invoked>",
                ( new D() {} ).getLong(),
                isE( f.getG() ), Clazz.isE( new F().getG() ) );

        final boolean check = b != null
                && b.getC().getD().getLong() >= 0
                && ! isE( f.getG() );

        out.printf( "check=%s%n", check );
        return check;
    }
}

Test class

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

class ClazzTest {

    @InjectMocks
    Clazz clazz = new Clazz();

    @Mock private B b;
    @Mock private C c;
    @Mock private D d;
    @Spy private F f;

    @BeforeEach
    void beforeEach() {
        openMocks( this );
    }

    @Test
    void testMocked() {
        when( b.getC() ).thenReturn( c );
        when( c.getD() ).thenReturn( d );
        when( d.getLong() ).thenReturn( 0 );
        when( f.getG() ).thenReturn( new G() );

        assertTrue( clazz.method( b, "mocked" ) );
        assertFalse( clazz.method( null, "mocked" ) );
    }

    @Test
    void testOriginal() {
        assertFalse( clazz.method( null, "original" ) );
        assertThrows( NullPointerException.class, () -> clazz.method( new B(), "original" ) );
        System.out.println( "expected <NPE thrown>" );
    }
}

Output

---- mocked
b=b
long=0, original: -1
isE=false, original: true
check=true
---- mocked
b=null
long=<not invoked>, original: -1
isE=false, original: true
check=false
---- original
b=null
long=<not invoked>, original: -1
isE=true, original: true
check=false
---- original
b=igb.so.B@8dfe921
<expected NPE thrown>
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
0

Right click on the whole condition -> Extract to new method

This will create a new method. You can mock as you see fit and use it in your tests.

LearningEveryday
  • 584
  • 1
  • 3
  • 13