Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffsheets/f13df334005065e5aa26 to your computer and use it in GitHub Desktop.
Save jeffsheets/f13df334005065e5aa26 to your computer and use it in GitHub Desktop.
Spring Async ListenableFutureCallback Spock test to validate that onFailure is handling exceptions raised in Async method
package com.sheetsj.spring.async.test
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.annotation.Async
import org.springframework.scheduling.annotation.AsyncResult
import org.springframework.scheduling.annotation.EnableAsync
import org.springframework.test.context.ContextConfiguration
import org.springframework.util.concurrent.ListenableFuture
import org.springframework.util.concurrent.ListenableFutureCallback
import spock.lang.Specification
import javax.inject.Inject
/**
* Validate onFailure handles the exception raised in Async method
* A test case for https://jira.spring.io/browse/SPR-12797
* It was fixed in Spring 4.1.6
*/
@ContextConfiguration
class SpringAsyncListenableFutureCallbackSpec extends Specification {
static class AsyncWorker {
@Async
ListenableFuture<String> doAsyncException() {
println 'throw exception'
if (true) throw new RuntimeException('testing async exceptions')
new AsyncResult('exception was thrown')
}
@Async
ListenableFuture<String> doAsyncSuccess() {
println 'success'
new AsyncResult('success')
}
}
@EnableAsync
@Configuration
static class Config {
@Bean
AsyncWorker asyncWorker() { new AsyncWorker() }
}
@Inject
AsyncWorker asyncWorker
def failureFound = false
def successFound = false
def callbackFinished = false
def startTime = System.currentTimeMillis()
ListenableFutureCallback<String> callback = new ListenableFutureCallback<String>() {
@Override
void onFailure(Throwable ex) {
failureFound = true
callbackFinished = true
}
@Override
void onSuccess(String result) {
successFound = true
callbackFinished = true
}
}
def "Callback correctly handles a raised exception"() {
when: 'async promise callback is created and registered'
ListenableFuture<String> promise = asyncWorker.doAsyncException()
promise.addCallback(callback)
while (!callbackFinished && (System.currentTimeMillis() - startTime < 5000)) {
//wait until done or 5 seconds
}
then:
failureFound
!successFound
}
def "Callback correctly handles a success"() {
when: 'async promise callback is created and registered'
ListenableFuture promise = asyncWorker.doAsyncSuccess()
promise.addCallback(callback)
while (!callbackFinished && (System.currentTimeMillis() - startTime < 5000)) {
//wait until done or 5 seconds
}
then:
!failureFound
successFound
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment