正如@deterb 建议的那样,使用 Mockito 是可能的,但您必须知道方法名称,或者您必须为每种方法设置期望。这是一个例子:
模拟界面:
public interface MyInterface {
void allowedMethod();
void disallowedMethod();
}
捕获的用户类AssertionError
:
public class UserClass {
public UserClass() {
}
public static void throwableCatcher(final MyInterface myInterface) {
try {
myInterface.allowedMethod();
myInterface.disallowedMethod();
} catch (final Throwable t) {
System.out.println("Catched throwable: " + t.getMessage());
}
}
}
还有 Mockito 测试:
@Test
public void testMockito() throws Exception {
final MyInterface myInterface = mock(MyInterface.class);
UserClass.throwableCatcher(myInterface);
verify(myInterface, never()).disallowedMethod(); // fails here
}
EasyMock 也是如此,但它需要一些工作:
@Test
public void testEasyMock() throws Exception {
final AtomicBoolean called = new AtomicBoolean();
final MyInterface myInterface = createMock(MyInterface.class);
myInterface.allowedMethod();
myInterface.disallowedMethod();
final IAnswer<? extends Object> answer = new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
System.out.println("answer");
called.set(true);
throw new AssertionError("should not call");
}
};
expectLastCall().andAnswer(answer).anyTimes();
replay(myInterface);
UserClass.throwableCatcher(myInterface);
verify(myInterface);
assertFalse("called", called.get()); // fails here
}
不幸的是,您还必须知道这里的方法名称,并且您必须定义期望,例如myInterface.disallowedMethod()
和expectLastCall().andAnswer(answer).anyTimes()
。
Proxy
另一种可能性是使用类(使用 custom )创建代理InvocationHandler
并将其用作模拟对象。它肯定需要更多的工作,但它可能是最可定制的解决方案。
最后不要忘记,也可以创建自定义实现,无论是否委托 EasyMock 模拟对象。这是一个有委托的:
public class MockedMyInterface implements MyInterface {
private final MyInterface delegate;
private final AtomicBoolean called = new AtomicBoolean();
public MockedMyInterface(final MyInterface delegate) {
this.delegate = delegate;
}
@Override
public void allowedMethod() {
delegate.allowedMethod();
}
@Override
public void disallowedMethod() {
called.set(true);
throw new AssertionError("should not call");
}
public boolean isCalled() {
return called.get();
}
}
并对其进行测试:
@Test
public void testEasyMockWithCustomClass() throws Exception {
final MyInterface myInterface = createMock(MyInterface.class);
myInterface.allowedMethod();
final MockedMyInterface mockedMyInterface =
new MockedMyInterface(myInterface);
replay(myInterface);
UserClass.throwableCatcher(mockedMyInterface);
verify(myInterface);
assertFalse("called", mockedMyInterface.isCalled()); // fails here
}