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
.
myFunction调用anotherFunction并返回anotherFunction的结果。
But it's not returning 1
and printing "true
" like I would expect, instead it's still doing its real functionality.
但它并没有像我期望的那样返回1并打印“真实”,而是仍然在做它真正的功能。
What am I missing here?
我在这里想念的是什么?
1 个解决方案
#1
2
An instance of AnotherClass is created inside myFunction then the instance is used to call secondClass.anotherFunction from inside myFunction.
在myFunction中创建了AnotherClass的实例,然后该实例用于从myFunction内部调用secondClass.anotherFunction。
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.
你要么重构注入第二个类,要么通过构造函数或方法参数,这是一个干净的代码设计,或者你使用powermock来模拟第二类的初始化,在我看来这是一个糟糕的设计。
@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
参考如何模拟新对象的构造
#1
2
An instance of AnotherClass is created inside myFunction then the instance is used to call secondClass.anotherFunction from inside myFunction.
在myFunction中创建了AnotherClass的实例,然后该实例用于从myFunction内部调用secondClass.anotherFunction。
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.
你要么重构注入第二个类,要么通过构造函数或方法参数,这是一个干净的代码设计,或者你使用powermock来模拟第二类的初始化,在我看来这是一个糟糕的设计。
@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
参考如何模拟新对象的构造