how to accessing @autowired variable in mvn install

Viewed 40

i have these 2 classes for integration testing using JUnit

@Slf4j
@Component
public class KafkaTestHelper {
    private final ConcurrentHashMap<String, ConsumerRecord<String, String>> messages = new ConcurrentHashMap<>();

    @KafkaListener(topics = "#{kafkaTestHelper.getTopics()}")
    public void onListen(ConsumerRecord<String, String> record) {
        log.info("#OnListen topic : {}, record : {}", record.topic(), record);
        this.messages.put(record.topic(), record);
        log.info("put on object {}", System.identityHashCode(messages));
        printHashMap();
    }

     public String getMessageByTopic(String topic) {
        log.info("#trying to consume from {}", topic);
        log.info("consuming from object {}", System.identityHashCode(messages));
        printHashMap();
        String message = getMessage(topic);
        log.info("#returning message : {}", message);
        return message;
    }
}

and then test class that @Autowired class above

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ImsStockApplication.class,},
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest {
    @Autowired
    private KafkaTestHelper kafkaTestHelper;

    @Test
    public void success() throws Exception {

        producer.send("someTopics").block();

        String valueFail = kafkaTestHelper.getMessageByTopic("someTopic"); // always empty on mvn build
        Assert.assertNotNull(valueFail);
    }
}

So the idea was simple, my test class publishing topic, and then the topic consumed then publishing another topic as a result. The result listened in the helper and i want to assert it in my test class. If i build and run, this code was able to run perfectly fine, but, the problem is, when I did mvn install it is not. Then i tried to log the listening and consuming activity in my helper and found this behavior that I didnt understand

If i build and run this normally it will listening, storing, and consuming records from the same object messages

Receive from topic someTopics with message somerecords
#OnListen topic : someTopics, record : somerecords
put on object 1654595627          <- same object id

#trying to consume someTopics
consuming from object 1654595627  <- same object id

but when i did mvn install, it shows differently

Receive from topic someTopics with message somerecords
#OnListen topic someTopics, record : somerecords
put on object 1869941502            <- different object id

#trying to consume from someTopics
consuming from object 1398482101    <- different object id

the incoming records always stored in object 1869941502 and consume from object 1398482101

shouldn't it be the same like the example above? since it should be accessing the same object right? why it only happens on mvn install and not normal build from the IDE.

Any idea/solution guys? Please help, thanks

1 Answers

Your test logic is not valid.

The producer and consumer are processed on different threads. Even if you publish with that block() on the main JUnit thread, the consumption happens in fully different thread. And you cannot assert consumption result just immediately after publishing. You need to wait for some barrier to be sure that consumer receives the data.

I understand that it is not desirable to modify a production code of the listener for some testing purpose, so I'd suggest you take a look into a Awaitility utils to ask for data to assert during some period until it fails or fulfilled.

Probably until that valueFail != null.

Related