Alex_Pap
Alex_Pap

Reputation: 464

Can I Use @QuarkusTest to Replace JerseyTest in Spock Specifications?

I have many Spock specifications like the next one, that act as "unit tests" for the resource classes of a project. This is an Open Liberty application and now there's a need to migrate it in Quarkus.

class ExampleResourceSpec extends ResourceSpecification {

    static final String BASE_URL = '/myurl'

    @Shared
    private ExampleService service

    @Override
    protected createResource() {
        service = Mock()
        new ExampleResource(service)
    }

    def '200 response for a successful request'() {
        given: 'a valid request'
        MyRequest request = fixtures.createMyRequest()
        def jsonReq = createJsonMyRequest(request)

        when: 'performing the post request'
        def response = jerseyPost(jsonReq, BASE_URL)

        then: 'the service is called with correct values'
        1 * photoService.handle({ actualRequest ->
            actualRequest.field1 == request.field1 &&
            actualRequest.field2 == request.field2 &&
            actualRequest.field3 == request.field3 
        })

        and: 'the resource returns 200 status code'
        response.status == Response.Status.OK.statusCode
    }

    private Response jerseyPost(String jsonReq, String url) {
        jerseyTest
                .target(url)
                .request()
                .post(Entity.json(jsonReq))
    }

    private createJsonMyRequest(MyRequest request) {
        def jsonSlurper = new JsonSlurper()
        def parsedJson = jsonSlurper.parseText(jsonb.toJson(request))

        return new JsonBuilder(parsedJson).toString()
    }
}

For these tests, JerseyTest was used to spin up a Grizzly Server with the necessary Resource Configuration that can be reflected on the next class:

abstract class ResourceSpecification extends Specification {

    JerseyTest jerseyTest

    protected abstract createResource();

    def setup() {
        jerseyTest = new JerseyTest() {
            @Override
            protected Application configure() {
                new ResourceConfig()
                        .register(createResource())
                        .register(MyAwesomeExceptionMapper)
            }
        }
        jerseyTest.setUp()
    }

    def parse(Response response) {
        jsonb.fromJson(response.readEntity(String), Map.class)
    }

    def cleanup() {
        jerseyTest.tearDown()
    }
}

However, the migration in Quarkus raises some major challenges since the latter does not support Spock. Moreover, there's a need to avoid using the JerseyTest dependencies and rely on Quarkus capabilities to keep these tests alive by particularly using the @QuarkusTest annotation that spins up a server. As you may suspect, the tests are many and I am trying to avoid to re-write all of them in JUnit5.

Things I have tried so far:

  1. Used RestAssured instead of Jersey for the actual HTTP call along with a GrizzlyHttpServerFactory to spin up a server. That worked perfectly but it still violates the requirement to avoid using external dependencies and relying on Quarkus.
  2. Removed the GrizzlyHttpServerFactory and added the @QuarkusTest annotation on my ResourceSpecification class, in hope to start the Quarkus Server. However, RestAssured is unable to establish a connection to the server thus resulting in a ConnectionException.

I suspect that this happens because there is no integration between Spock and ArC which is the CDI container in Quarkus.

Is it possible to achieve what I want or should I re-write the tests in JUnit5? Also, in case the latter must be done, can I use RestAssured along with Mockito somehow? I know that RestAssured is mostly for integration tests.

Upvotes: 0

Views: 37

Answers (0)

Related Questions