在 Expectations 块中模拟私有方法会导致 "IllegalStateException: Missing invocation to mocked type at this point"
Mocking a private method in an Expectations block causes "IllegalStateException: Missing invocation to mocked type at this point"
我有一个使用 JMockit Expectations
块的 JUnit 测试:
@Tested
private MyTestedClass myTestedClass;
@Injectable
private MyOtherClass myOtherClass;
@Test
public void publicBooleanMethodTest() {
new Expectations() {{
invoke(myOtherClass, "privateMethod");
result = true;
}};
myTestedClass.run(); // Calls myOtherClass.privateMethod();
}
但是,这会导致以下错误:
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter
如您所见,myClass
是通过 @Injectable
模拟的,所以我不确定为什么会发生错误。我还发现,如果我将 privateMethod()
的范围更改为 public,一切正常。
这是怎么回事,我该如何解决?它在 JMockit 1.22 中运行良好,但现在在 JMockit 1.23 及更高版本中失败。
JMockit 1.23 删除了对 Expectations
块中模拟私有方法的支持。来自 release notes:
Version 1.23 (Apr 24, 2016):
- Dropped support for the mocking of private methods/constructors when using the Expectations API, to prevent misuse. If still needed, they can be mocked or stubbed out with the application of a
MockUp<T>
.
不幸的是,错误的错误消息目前被视为 "too costly too fix" by the development team. 因此,在 JMockit 1.28 中添加了更好的错误消息讨论。
错误日志说使用 MockUp<T>
作为替代。在这种情况下,代码如下:
@Tested
private MyTestedClass myTestedClass;
@Injectable
private MyOtherClass myOtherClass;
@Test
public void publicBooleanMethodTest() {
// Partially mock myOtherClass
new MockUp<MyOtherClass>(myOtherClass) {
@Mock boolean privateBooleanMethod() {
return true;
}
};
myTestedClass.run(); // Calls myOtherClass.privateMethod();
}
我有一个使用 JMockit Expectations
块的 JUnit 测试:
@Tested
private MyTestedClass myTestedClass;
@Injectable
private MyOtherClass myOtherClass;
@Test
public void publicBooleanMethodTest() {
new Expectations() {{
invoke(myOtherClass, "privateMethod");
result = true;
}};
myTestedClass.run(); // Calls myOtherClass.privateMethod();
}
但是,这会导致以下错误:
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter
如您所见,myClass
是通过 @Injectable
模拟的,所以我不确定为什么会发生错误。我还发现,如果我将 privateMethod()
的范围更改为 public,一切正常。
这是怎么回事,我该如何解决?它在 JMockit 1.22 中运行良好,但现在在 JMockit 1.23 及更高版本中失败。
JMockit 1.23 删除了对 Expectations
块中模拟私有方法的支持。来自 release notes:
Version 1.23 (Apr 24, 2016):
- Dropped support for the mocking of private methods/constructors when using the Expectations API, to prevent misuse. If still needed, they can be mocked or stubbed out with the application of a
MockUp<T>
.
不幸的是,错误的错误消息目前被视为 "too costly too fix" by the development team. 因此,在 JMockit 1.28 中添加了更好的错误消息讨论。
错误日志说使用 MockUp<T>
作为替代。在这种情况下,代码如下:
@Tested
private MyTestedClass myTestedClass;
@Injectable
private MyOtherClass myOtherClass;
@Test
public void publicBooleanMethodTest() {
// Partially mock myOtherClass
new MockUp<MyOtherClass>(myOtherClass) {
@Mock boolean privateBooleanMethod() {
return true;
}
};
myTestedClass.run(); // Calls myOtherClass.privateMethod();
}