MyClass firstClass = PowerMockito.spy(new MyClass());
AnotherClass secondClass;
secondClass = PowerMockito.mock(AnotherClass.class);
PowerMockito.when(secondClass.anotherFunction(Mockito.any()).thenReturn(1);
int myInt = firstClass.myFunction();
if (myInt == 1) {
System.out.println("true");
}
myFunction
calls anotherFunction
and returns the results of anotherFunction
.
But it's not returning 1
and printing "true
" like I would expect, instead it's still doing its real functionality.
What am I missing here?
An instance of AnotherClass is created inside myFunction then the instance is used to call secondClass.anotherFunction from inside myFunction.
Right. That means that the real instance is used, not the mock. The method under test is tightly coupled to the dependency because it creates a real instance on its own
public class MyClass {
public int myFunction() {
AnotherClass secondClass = new AnotherClass();
int result = secondClass.anotherFunction(someValue);
//...
return result;
}
}
How can I use the mocked instance instead?
You either refactor to have the second class injected, either via constructor or method parameter, which is a clean code design or you use powermock to mock the initialization of the second class, which in my opinion is poor design.
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class) //<-- you must prepare the class creating the new instance
public class MyClassTest {
@Test
public void test() {
//Arrange
int expected = 1;
//Mock second class
AnotherClass secondClass;
secondClass = PowerMockito.mock(AnotherClass.class);
PowerMockito.when(secondClass.anotherFunction(Mockito.any()).thenReturn(expected);
//mocking initialization of second class withing first class
PowerMockito.whenNew(AnotherClass.class).withNoArguments().thenReturn(secondClass);
MyClass firstClass = new MyClass();
//Act
int actual = firstClass.myFunction();
//Assert
assertEquals(expected, actual);
}
}
Reference How to mock construction of new objects