Allow multiple listeners on ResponseBodyEmitter
Prior to this commit, `ResponseBodyEmitter` woud accept a single `Runnable` callback on each of its `onTimeout`, `onError` or `onCompletion` methods. This would limit the developers' ability to register multiple sets of callbacks: one for managing the publication of streaming values, another one for managing other concerns like keep-alive signals to maintain the connection. This commit now allows multiple calls to `onTimeout`, `onError` and `onCompletion` and will register all callbacks accordingly. Closes gh-33356
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -31,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThatIOException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anySet;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.willThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -41,6 +43,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Tomasz Nurkiewicz
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ResponseBodyEmitterTests {
|
||||
@@ -197,6 +200,25 @@ public class ResponseBodyEmitterTests {
|
||||
verify(runnable).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleOnTimeoutCallbacks() throws Exception {
|
||||
this.emitter.initialize(this.handler);
|
||||
|
||||
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
|
||||
verify(this.handler).onTimeout(captor.capture());
|
||||
verify(this.handler).onCompletion(any());
|
||||
|
||||
Runnable first = mock();
|
||||
Runnable second = mock();
|
||||
this.emitter.onTimeout(first);
|
||||
this.emitter.onTimeout(second);
|
||||
|
||||
assertThat(captor.getValue()).isNotNull();
|
||||
captor.getValue().run();
|
||||
verify(first).run();
|
||||
verify(second).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
void onCompletionBeforeHandlerInitialized() throws Exception {
|
||||
Runnable runnable = mock();
|
||||
@@ -228,4 +250,42 @@ public class ResponseBodyEmitterTests {
|
||||
verify(runnable).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleOnCompletionCallbacks() throws Exception {
|
||||
this.emitter.initialize(this.handler);
|
||||
|
||||
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
|
||||
verify(this.handler).onTimeout(any());
|
||||
verify(this.handler).onCompletion(captor.capture());
|
||||
|
||||
Runnable first = mock();
|
||||
Runnable second = mock();
|
||||
this.emitter.onCompletion(first);
|
||||
this.emitter.onCompletion(second);
|
||||
|
||||
assertThat(captor.getValue()).isNotNull();
|
||||
captor.getValue().run();
|
||||
verify(first).run();
|
||||
verify(second).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleOnErrorCallbacks() throws Exception {
|
||||
this.emitter.initialize(this.handler);
|
||||
|
||||
ArgumentCaptor<Consumer<Throwable>> captor = ArgumentCaptor.<Consumer<Throwable>, Consumer>forClass(Consumer.class);
|
||||
verify(this.handler).onError(captor.capture());
|
||||
|
||||
Consumer<Throwable> first = mock();
|
||||
Consumer<Throwable> second = mock();
|
||||
this.emitter.onError(first);
|
||||
this.emitter.onError(second);
|
||||
|
||||
assertThat(captor.getValue()).isNotNull();
|
||||
IllegalStateException illegalStateException = new IllegalStateException();
|
||||
captor.getValue().accept(illegalStateException);
|
||||
verify(first).accept(eq(illegalStateException));
|
||||
verify(second).accept(eq(illegalStateException));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user