Skip to content

Commit

Permalink
Polishing StandardServletAsyncWebRequestTests
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoyanchev committed Mar 5, 2024
1 parent cfd0aee commit 822e244
Showing 1 changed file with 91 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import jakarta.servlet.AsyncEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import org.springframework.web.testfixture.servlet.MockAsyncContext;
Expand All @@ -32,7 +33,8 @@
import static org.mockito.Mockito.verify;

/**
* A test fixture with a {@link StandardServletAsyncWebRequest}.
* Tests for {@link StandardServletAsyncWebRequest}.
*
* @author Rossen Stoyanchev
*/
class StandardServletAsyncWebRequestTests {
Expand All @@ -49,120 +51,109 @@ void setup() {
this.request = new MockHttpServletRequest();
this.request.setAsyncSupported(true);
this.response = new MockHttpServletResponse();
this.asyncRequest = new StandardServletAsyncWebRequest(this.request, this.response);
this.asyncRequest.setTimeout(44*1000L);
}


@Test
void isAsyncStarted() {
assertThat(this.asyncRequest.isAsyncStarted()).isFalse();
this.asyncRequest.startAsync();
assertThat(this.asyncRequest.isAsyncStarted()).isTrue();
}

@Test
void startAsync() {
this.asyncRequest.startAsync();

MockAsyncContext context = (MockAsyncContext) this.request.getAsyncContext();
assertThat(context).isNotNull();
assertThat(context.getTimeout()).as("Timeout value not set").isEqualTo((44 * 1000));
assertThat(context.getListeners()).containsExactly(this.asyncRequest);
}

@Test
void startAsyncMultipleTimes() {
this.asyncRequest.startAsync();
this.asyncRequest.startAsync();
this.asyncRequest.startAsync();
this.asyncRequest.startAsync(); // idempotent

MockAsyncContext context = (MockAsyncContext) this.request.getAsyncContext();
assertThat(context).isNotNull();
assertThat(context.getListeners()).hasSize(1);
}

@Test
void startAsyncNotSupported() {
this.request.setAsyncSupported(false);
assertThatIllegalStateException().isThrownBy(
this.asyncRequest::startAsync)
.withMessageContaining("Async support must be enabled");
this.asyncRequest = new StandardServletAsyncWebRequest(this.request, this.response);
this.asyncRequest.setTimeout(44 * 1000L);
}

@Test
void startAsyncAfterCompleted() throws Exception {
this.asyncRequest.onComplete(new AsyncEvent(new MockAsyncContext(this.request, this.response)));
assertThatIllegalStateException().isThrownBy(this.asyncRequest::startAsync)
.withMessage("Cannot start async: [COMPLETED]");

@Nested
class StartAsync {

@Test
void isAsyncStarted() {
assertThat(asyncRequest.isAsyncStarted()).isFalse();

asyncRequest.startAsync();

assertThat(asyncRequest.isAsyncStarted()).isTrue();
}

@Test
void startAsync() {
asyncRequest.startAsync();

MockAsyncContext context = (MockAsyncContext) request.getAsyncContext();
assertThat(context).isNotNull();
assertThat(context.getTimeout()).as("Timeout value not set").isEqualTo((44 * 1000));
assertThat(context.getListeners()).containsExactly(asyncRequest);
}

@Test
void startAsyncMultipleTimes() {
asyncRequest.startAsync();
asyncRequest.startAsync();
asyncRequest.startAsync();
asyncRequest.startAsync();

MockAsyncContext context = (MockAsyncContext) request.getAsyncContext();
assertThat(context).isNotNull();
assertThat(context.getListeners()).hasSize(1);
}

@Test
void startAsyncNotSupported() {
request.setAsyncSupported(false);
assertThatIllegalStateException()
.isThrownBy(asyncRequest::startAsync)
.withMessageContaining("Async support must be enabled");
}

@Test
void startAsyncAfterCompleted() throws Exception {
asyncRequest.startAsync();
asyncRequest.onComplete(new AsyncEvent(new MockAsyncContext(request, response)));

assertThatIllegalStateException()
.isThrownBy(asyncRequest::startAsync)
.withMessage("Cannot start async: [COMPLETED]");
}

@Test
void startAsyncAndSetTimeout() {
asyncRequest.startAsync();
assertThatIllegalStateException().isThrownBy(() -> asyncRequest.setTimeout(25L));
}
}

@Test
void onTimeoutDefaultBehavior() throws Exception {
this.asyncRequest.onTimeout(new AsyncEvent(new MockAsyncContext(this.request, this.response)));
assertThat(this.response.getStatus()).isEqualTo(200);
}

@Test
void onTimeoutHandler() throws Exception {
Runnable timeoutHandler = mock();
this.asyncRequest.addTimeoutHandler(timeoutHandler);
this.asyncRequest.onTimeout(new AsyncEvent(new MockAsyncContext(this.request, this.response)));
verify(timeoutHandler).run();
}
@Nested
class AsyncListenerHandling {

@Test
void onErrorHandler() throws Exception {
Consumer<Throwable> errorHandler = mock();
this.asyncRequest.addErrorHandler(errorHandler);
Exception e = new Exception();
this.asyncRequest.onError(new AsyncEvent(new MockAsyncContext(this.request, this.response), e));
verify(errorHandler).accept(e);
}
@Test
void onTimeoutHandler() throws Exception {
Runnable handler = mock();
asyncRequest.addTimeoutHandler(handler);

@Test
void setTimeoutDuringConcurrentHandling() {
this.asyncRequest.startAsync();
assertThatIllegalStateException().isThrownBy(() ->
this.asyncRequest.setTimeout(25L));
}
asyncRequest.startAsync();
asyncRequest.onTimeout(new AsyncEvent(new MockAsyncContext(request, response)));

@Test
void onCompletionHandler() throws Exception {
Runnable handler = mock();
this.asyncRequest.addCompletionHandler(handler);
verify(handler).run();
}

this.asyncRequest.startAsync();
this.asyncRequest.onComplete(new AsyncEvent(this.request.getAsyncContext()));
@Test
void onErrorHandler() throws Exception {
Exception ex = new Exception();
Consumer<Throwable> handler = mock();
asyncRequest.addErrorHandler(handler);

verify(handler).run();
assertThat(this.asyncRequest.isAsyncComplete()).isTrue();
}
asyncRequest.startAsync();
asyncRequest.onError(new AsyncEvent(new MockAsyncContext(request, response), ex));

// SPR-13292
verify(handler).accept(ex);
}

@Test
void onErrorHandlerAfterOnErrorEvent() throws Exception {
Consumer<Throwable> handler = mock();
this.asyncRequest.addErrorHandler(handler);
@Test
void onCompletionHandler() throws Exception {
Runnable handler = mock();
asyncRequest.addCompletionHandler(handler);

this.asyncRequest.startAsync();
Exception e = new Exception();
this.asyncRequest.onError(new AsyncEvent(this.request.getAsyncContext(), e));
asyncRequest.startAsync();
asyncRequest.onComplete(new AsyncEvent(request.getAsyncContext()));

verify(handler).accept(e);
verify(handler).run();
assertThat(asyncRequest.isAsyncComplete()).isTrue();
}
}

@Test
void onCompletionHandlerAfterOnCompleteEvent() throws Exception {
Runnable handler = mock();
this.asyncRequest.addCompletionHandler(handler);

this.asyncRequest.startAsync();
this.asyncRequest.onComplete(new AsyncEvent(this.request.getAsyncContext()));

verify(handler).run();
assertThat(this.asyncRequest.isAsyncComplete()).isTrue();
}
}

0 comments on commit 822e244

Please sign in to comment.