Sarthak Nigam
Sarthak Nigam

Reputation: 117

How to mock the method of an object in which mocks are injected

I am writing tests for a class using mockito and testng. The class to be tested has several dependencies which need to be mocked and injected. The class to be tested has the following profile

class A{
    @Autowired
    private Object1;
    @Autowired
    private Object2;
    Object3 methodToBeTested (){
           //some code
           method2();
           //some code
    }
    boolean method2(){
        //some calls to Database that are not operational
    }
}

In my test class, I am declaring the objects Object1 and Object2 as mocks and initializing them as below

@Mock
Object1 ob1;
@Mock
Object2 ob2;
@InjectMocks
A a = new A();

@Test
public void ATest(){
     Object3 ob3;
     when(ob1.someMethod()).thenReturn(someObject);
     when(ob2.someMethos()).thenReturn(someOtherObject);
     ob3 = a.methodToBeTested();
     assertNotNull(ob3);
}

The problem arises because I have to mock the call to method2 of class A as well as it has some calls that are not operational in testing phase. Also mockito does not allow an object to have both @Mocks and @InjectMocks annotations simultaneously. Is there a way to move forward with the testing without modifying code for Class A (don't want to modify it just for testing).

Upvotes: 0

Views: 92

Answers (1)

JB Nizet
JB Nizet

Reputation: 692073

You need to spy on the real A object, as explained in the documentation:

@Mock
Object1 ob1;

@Mock
Object2 ob2;

@InjectMocks
A a = new A();

@Test
public void ATest(){
    A spy = spy(a);

    doReturn(true).when(spy).method2();

    Object3 ob3;
    when(ob1.someMethod()).thenReturn(someObject);
    when(ob2.someMethos()).thenReturn(someOtherObject);

    ob3 = spy.methodToBeTested();

    assertNotNull(ob3);
}

Note that this has a good chance of indicating a code smell. The method2() should perhaps be moved into another class, on which A would depend.

Upvotes: 2

Related Questions