Jmockit:验证接口字段的调用方法
Jmockit: Verify call method of interface field
使用的 JMockit 版本:1.21
我有这样的界面。
测试接口:
public interface TestInterface {
boolean callMethod();
}
一个TestClass有字段是那个接口的一个实例
测试类:
public class TestClass {
private final TestInterface inner = new TestInterface() {
@Override
public boolean callMethod() {
subMethod();
return false;
}
};
public void subMethod() { System.out.println("Sub method");
};
}
我在本教程中尝试通过伪造接口来验证调用方法。
http://jmockit.org/tutorial/Faking.html#interfacesd
测试方法。
public class TestInterfaceTest {
TestClass sut;
@Before
public void setUp() {
sut = Deencapsulation.newInstance(TestClass.class);
}
@Test
public void mockAllClassesImplementingAnInterface() {
TestInterface testInterface = new MockUp<TestInterface>() {
@Mock
public boolean callMethod(Invocation inv) {
inv.proceed(); // throw exception here -> Will my expected method be called here?
return true;
}
}.getMockInstance();
Deencapsulation.setField(sut, "INTER", testInterface);
new NonStrictExpectations() {
{
Deencapsulation.invoke(sut, "subMethod");
}
};
Boolean result = Deencapsulation.invoke(Deencapsulation.getField(sut, "INTER"), "callMethod");
assertTrue(result);
new Verifications() {
{
Deencapsulation.invoke(sut, "subMethod"); times = 1;
}
};
}
}
java.lang.IllegalArgumentException: No class with name
"ndroid.examples.helloandroid.$Impl_TestInterface" found
如果你们不介意的话,请告诉我如何解决这个byg。非常感谢。
根据我对这个问题的重新评估,你的问题似乎出在 inv.proceed()
行。您不能在界面的 Mockup
中包含该行。
Invocation.proceed()
用于当您希望 MockUp
实现进入实际代码时。但是因为您正在模拟一个接口,没有真正的代码。您可能认为是因为您的 TestClass
实现具有接口的匿名实现,但是 MockUp
对匿名 class 一无所知;它正在制作界面模型,而不是您的匿名实现模型。
如果你去掉那一行,调用 Invocation.proceed()
,我想你会发现你的错误消失了。
基于@dcsohl 的指导。下面的代码对我有用。
@Test
public void mockAllClassesImplementingAnInterface() {
// Partial mocking
new NonStrictExpectations(sut) {
{
sut.subMethod();
}
};
// Actual invocation
Deencapsulation.invoke(Deencapsulation.getField(sut, "inner"), "callMethod");
// Verify
new Verifications() {
{
Deencapsulation.invoke(sut, "subMethod");
times = 1;
}
};
}
使用的 JMockit 版本:1.21 我有这样的界面。 测试接口:
public interface TestInterface {
boolean callMethod();
}
一个TestClass有字段是那个接口的一个实例 测试类:
public class TestClass {
private final TestInterface inner = new TestInterface() {
@Override
public boolean callMethod() {
subMethod();
return false;
}
};
public void subMethod() { System.out.println("Sub method");
};
}
我在本教程中尝试通过伪造接口来验证调用方法。 http://jmockit.org/tutorial/Faking.html#interfacesd
测试方法。
public class TestInterfaceTest {
TestClass sut;
@Before
public void setUp() {
sut = Deencapsulation.newInstance(TestClass.class);
}
@Test
public void mockAllClassesImplementingAnInterface() {
TestInterface testInterface = new MockUp<TestInterface>() {
@Mock
public boolean callMethod(Invocation inv) {
inv.proceed(); // throw exception here -> Will my expected method be called here?
return true;
}
}.getMockInstance();
Deencapsulation.setField(sut, "INTER", testInterface);
new NonStrictExpectations() {
{
Deencapsulation.invoke(sut, "subMethod");
}
};
Boolean result = Deencapsulation.invoke(Deencapsulation.getField(sut, "INTER"), "callMethod");
assertTrue(result);
new Verifications() {
{
Deencapsulation.invoke(sut, "subMethod"); times = 1;
}
};
}
}
java.lang.IllegalArgumentException: No class with name "ndroid.examples.helloandroid.$Impl_TestInterface" found
如果你们不介意的话,请告诉我如何解决这个byg。非常感谢。
根据我对这个问题的重新评估,你的问题似乎出在 inv.proceed()
行。您不能在界面的 Mockup
中包含该行。
Invocation.proceed()
用于当您希望 MockUp
实现进入实际代码时。但是因为您正在模拟一个接口,没有真正的代码。您可能认为是因为您的 TestClass
实现具有接口的匿名实现,但是 MockUp
对匿名 class 一无所知;它正在制作界面模型,而不是您的匿名实现模型。
如果你去掉那一行,调用 Invocation.proceed()
,我想你会发现你的错误消失了。
基于@dcsohl 的指导。下面的代码对我有用。
@Test
public void mockAllClassesImplementingAnInterface() {
// Partial mocking
new NonStrictExpectations(sut) {
{
sut.subMethod();
}
};
// Actual invocation
Deencapsulation.invoke(Deencapsulation.getField(sut, "inner"), "callMethod");
// Verify
new Verifications() {
{
Deencapsulation.invoke(sut, "subMethod");
times = 1;
}
};
}