javaspringspring-bootgraphgraphql-spqr-spring-boot-starter

No GraphQL Service registered when running test with Spring Boot


I have an app, that contains both Camel (3.14) and GraphQL (starter, 0.0.6). App is build on top of Spring Boot (2.7.5).

App is working fine, but when running a test as follows:

@CamelSpringBootTest
@EnableAutoConfiguration
@SpringBootTest(
        properties = { "camel.springboot.name=camelTest" }
)
public class TestMailRoute
{
    @Autowired
    ProducerTemplate producerTemplate;

@EndpointInject("mock:test")
MockEndpoint mockEndpoint;

@Configuration
static class TestConfig {

    @Bean
    RoutesBuilder route() {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:feedback").to("mock:test");
                from("direct:users").to("mock:test");
                from("direct:mail").to("mock:test");
            }
        };
    }
}

@Test
public void shouldAutowireProducerTemplate() {
    assertNotNull(producerTemplate);
}
...
}

I've got an error:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.schema.GraphQLSchema]: Factory method 'graphQLSchema' threw exception; nested exception is java.lang.IllegalStateException: At least one top-level operation source must be registered
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 104 more
Caused by: java.lang.IllegalStateException: At least one top-level operation source must be registered
    at io.leangen.graphql.GraphQLSchemaGenerator.init(GraphQLSchemaGenerator.java:863)
    at io.leangen.graphql.GraphQLSchemaGenerator.generateExecutable(GraphQLSchemaGenerator.java:999)
    at io.leangen.graphql.GraphQLSchemaGenerator.generate(GraphQLSchemaGenerator.java:995)
    at io.leangen.graphql.spqr.spring.autoconfigure.BaseAutoConfiguration.graphQLSchema(BaseAutoConfiguration.java:269)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 105 more

After googling and debugging, I've found out, that my class annotated with @GraphQLApi is not being initiated, which probably cases the exception (in contrary, it is initiated when running app itself).

So I'm missing some configuration or I misconfigure somehow my test, but I don't have a clue how to fix it, so that my test is working. I've tried with @ContextConfiguration (and provide my @GraphQLApi class) but then there was different error.


Solution

  • To resolve the issue of missing GraphQL services during testing, ensure your @GraphQLApi annotated classes are included in the test context. Adjust your test class as follows:

    @CamelSpringBootTest
    @SpringBootTest(properties = { "camel.springboot.name=camelTest" })
    @EnableAutoConfiguration
    @ComponentScan(basePackages = "com.yourpackage.graphql") // Adjust the package
    public class TestMailRoute {
    
        @Autowired
        ProducerTemplate producerTemplate;
    
        @EndpointInject("mock:test")
        MockEndpoint mockEndpoint;
    
        @Configuration
        static class TestConfig {
    
            @Bean
            RoutesBuilder route() {
                return new RouteBuilder() {
                    @Override
                    public void configure() {
                        from("direct:feedback").to("mock:test");
                        from("direct:users").to("mock:test");
                        from("direct:mail").to("mock:test");
                    }
                };
            }
        }
    
        @Test
        public void shouldAutowireProducerTemplate() {
            assertNotNull(producerTemplate);
        }
    }