Hello everyone,

I have a weird behavior when working with spring-kafka-test's @EmbeddedKafka annotation. I am not certain whether this problem is linked to spring-kafka-test or spring-boot. This problem is reproduced with spring boot 2.6.7. Here's my issue :

A have a test class that auto-configures a bean of type AClass. When @EmbeddedKafka is present on the class this bean is created twice. If we remove the @EmbeddedKafka it is created once. This problem only happens with a @Nested class. In the following test, the assertEquals assertion will fail :

@SpringBootTest(classes = DemoApplicationTests.ATestConfiguration.class)
@EmbeddedKafka
class DemoApplicationTests {

    @Autowired
    private AClass aClass1;

    @Nested
    class NestedClass {
        @Test
        void equalsInjected(@Autowired AClass aClass2) {
            assertEquals(aClass1, aClass2);
        }
    }

    public static class AClass {
    }

    @TestConfiguration(proxyBeanMethods = false)
    static class ATestConfiguration {
        @Bean
        public AClass aClass() {
            return new AClass();
        }
    }
}

Here's a sample project with more test cases : bean-created-twice.zip

If you think this issue might be linked to spring-kafka instead, let me know and I will open it there.

Comment From: wilkinsona

This is indeed caused by @EmbeddedKafka. Its presence results in a cache miss when the test framework is creating the context for NestedTests preventing it from reusing the context that was created for DemoApplicationTests.

You can reproduce the problem without involving Spring Boot with the following code:

package com.example.demo;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.test.context.EmbeddedKafka;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

import com.example.demo.DemoApplicationTests.ATestConfiguration;

@EmbeddedKafka
@SpringJUnitConfig(ATestConfiguration.class)
class DemoApplicationTests {

    private static final AtomicInteger counter = new AtomicInteger();

    @Autowired
    private AClass aClass1;

    @Nested
    class NestedClass {
        @Test
        void equalsInjected(@Autowired AClass aClass2) {
            assertEquals(aClass1, aClass2);
        }

        @Test
        void equalsSize(@Autowired List<AClass> classes) {
            assertEquals(1, classes.size());
        }

        @Test
        void equalsCount() {
            assertEquals(2, counter.get());
        }
    }

    public static class AClass {
    }

    @Configuration(proxyBeanMethods = false)
    static class ATestConfiguration {
        @Bean
        public AClass aClass() {
            counter.incrementAndGet();
            return new AClass();
        }
    }
}

Can you please report this to the Spring Kafka project?