这似乎很容易,但我不知道该怎么做。我们有一个状态机,当触发转换时,事件通过EventManager类发送。这是在一个新线程中启动的,因为我们不希望在分发事件时阻塞当前线程。
假设我忘了在嘲笑时期待一个方法调用。测试现在应该失败了。但它并不是因为线程捕获了异常。我也不想传播期望,因为状态机在异常时停止。
public class TestStackoverflow {
@Test
public void test(){
EventManager eventManager = EasyMock.createStrictMock(EventManager.class);
EasyMock.replay(eventManager);
MyClass myClass = new MyClass();
myClass.executeStuff(eventManager);
EasyMock.verify(eventManager);
}
private class MyClass{
public void executeStuff(final EventManager eventManager){
new Thread() {
public void run() {
eventManager.sendEvent();
}
}.start();
}
}
interface EventManager{
public void sendEvent();
}
}
eventManager.sendEvent()抛出java.lang.AssertionError,但单元测试不会失败。
Exception in thread "Thread-0" java.lang.AssertionError:
Unexpected method call EventManager.sendEvent():
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
at at.ac.TestStackoverflow$EventManager$$EnhancerByCGLIB$$cbb0f0e1.sendEvent(<generated>)
at at.ac.TestStackoverflow$MyClass$1.run(TestStackoverflow.java:27)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.58 sec
我如何测试这种情况?
答案 0 :(得分:0)
即使异常确实传播回您的测试,它仍然可能无法正常工作,因为它看起来可能存在竞争条件。
例如,在您的测试中,&#34; executeStuff&#34;会启动线程,但它实际上可能没有机会直接运行。
如果主线程继续,它可能会进入&#34;验证&#34;在另一个线程有机会运行之前的声明。
如果稍微改变一下,以便在课堂外创建Thread,那么测试就会更容易。
然后,您可以使用UncaughtExceptionHandler来解决原始问题,例如......
public class TestStackoverflow {
@Test
public void test(){
TestExceptionHandler exceptionHandler = new TestExceptionHandler();
EventManager eventManager = EasyMock.createStrictMock(EventManager.class);
EasyMock.replay(eventManager);
// Create a MyClass - pass in the eventManager
MyClass myClass = new MyClass(eventManager);
// Create thread
Thread thread = new Thread(myClass);
thread.setUncaughtExceptionHandler(exceptionHandler);
// Run your code
thread.start();
// WAIT FOR THREAD TO FINISH
thread.join();
// Check no exceptions were thrown
exceptionHandler.verifyNoExceptions();
}
private class TestExceptionHandler implements UncaughtExceptionHandler {
private Throwable e;
@Override
public void uncaughtException(Thread t, Throwable e) {
this.e = e;
}
public void verifyNoExceptions() {
if(e != null) {
throw new AssertionError("BOOM! Exception caught", e);
}
}
}
private class MyClass implements Runnable {
private EventManager eventManager;
public MyClass(EventManager eventManager) {
this.eventManager = eventManager;
}
public void run(){
eventManager.sendEvent();
}
}
interface EventManager{
public void sendEvent();
}
}
答案 1 :(得分:0)
createStrictMock
所做的是它创建了一个类的严格模拟,如果在Testclass中以特定顺序不需要在代码中调用的方法,则会抛出异常。这导致Unexpected method call
例外(成功完成测试用例不应该首先出现例外情况)。
你需要创建一个漂亮的模拟,即Easymock.createNiceMock(EventManager.class);
这个例外应该解决
祝你好运!