7

I am facing a very annoying problem, during test process in my Spring Boot application. I have an application that uses Kafka Streams and declares them in a dedicated configuration file.

@EnableKafka
@EnableKafkaStreams
@Configuration
public class KafkaStreamConfiguration {
    @Bean(name = KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)
    public StreamsConfig kStreamsConfigs() {
        // Omissis
    }
    @Bean
    public KStream<String, String> kStream() {
        // Omissis
    }
}

My application also exposes a dedicated REST API using a Spring @RestController. I want to test this rest controller in isolation, with something like the following.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class RestControllerTest {
    @Test
    public void someFancyTest() {
        // Omissis
    }
}

The problem is that I cannot avoid Spring context to start the streams defined in KafkaStreamConfiguration class. I did not find any way to exclude this class from Spring context during the execution of RestControllerTest.

I do not want to declare a KafkaEmbedded instance in RestControllerTest class. It seems to me a nonsense.

Is it possible? How can I slice tests to maintain some order of independence?

The application class is as simple as possible.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

I am using Spring Boot version 1.5.8 and Kafka version 0.10.2.1.

riccardo.cardin
  • 7,971
  • 5
  • 57
  • 106

1 Answers1

3

I build tests for my test controllers where I explicitly define configuration classes. This allows me to mix real configuration and mock configuration as required. So you should be able to mock out Kafka and anything else you aren't testing.

This is how I annotate the test class:

@RunWith(SpringRunner.class)
@Import({
    MockIntegrationConfiguration.class,
    RealConfiguration.class,
})
@WebMvcTest(RestController.class)
public class RestControllerTest {

And I auto wire MockMvc to test the API:

@Autowired
private MockMvc mockMvc;
James
  • 1,095
  • 7
  • 20
  • So, every test that is not related to Kafka stream should declare its slice, shouldn’t it? It should be better to exclude the configuration of streams, instead. – riccardo.cardin Feb 13 '18 at 16:51
  • Another trick I use is `profiles`. Where I might use `default` etc for production code and `test` to apply a mock configuration. – James Feb 13 '18 at 19:25
  • Well, I don’t think the last thing you said is related to my question ;) – riccardo.cardin Feb 13 '18 at 19:43
  • Maybe not but I do use Spring profiles to enable or disable different configurations from production for testing. I use either explicit configuration or Spring profiles to exclude configuration for testing. – James Feb 13 '18 at 19:52
  • You don't need to `@Import` external configuration, if you use the slice `@WebMvcTest` :) – riccardo.cardin Feb 14 '18 at 15:09