Search code examples
javaautomated-testskaratecucumber-java

How to reuse util java class into other karate project?


I was working with karate framework to test my rest service and it work great, however I have service that consume message from kafka topic then persist on mongo to finally notify kafka. I made a java producer on my karate project, it called by js to be used by feature. Then I have a consumer to check the message

Feature:

    * def kafkaProducer = read('../js/KafkaProducer.js')

JS:

function(kafkaConfiguration){
var Producer = Java.type('x.y.core.producer.Producer');
var producer = new Producer(kafkaConfiguration);
return producer;
}

Java:

public class Producer {

private static final Logger LOGGER = LoggerFactory.getLogger(Producer.class);

private static final String KEY = "C636E8E238FD7AF97E2E500F8C6F0F4C";
private KafkaConfiguration kafkaConfiguration;
private ObjectMapper mapper;
private AESEncrypter aesEncrypter;


public Producer(KafkaConfiguration kafkaConfiguration) {
    kafkaConfiguration.getProperties().put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
    kafkaConfiguration.getProperties().put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArraySerializer");
    this.kafkaConfiguration = kafkaConfiguration;
    this.mapper = new ObjectMapper();
    this.aesEncrypter = new AESEncrypter(KEY);
}


public String produceMessage(String payload) {

  // Just notify kafka with payload and return id of payload
}

Other class

public class KafkaConfiguration {

private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConfiguration.class);

private Properties properties;

public KafkaConfiguration(String host) {

    try {
        properties = new Properties();
        properties.put(BOOTSTRAP_SERVERS_CONFIG, host);
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, "karate-integration-test");
        properties.put(ConsumerConfig.CLIENT_ID_CONFIG, "offset123");
        properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
    } catch (Exception e) {
        LOGGER.error("Fail creating the consumer...", e);
        throw e;
    }
}

public Properties getProperties() {
    return properties;
}

public void setProperties(Properties properties) {
    this.properties = properties;
}
}

I'd would like to use the producer code with anotation like cucumber does like:

@Then("^Notify kafka with payload (-?\\d+)$")
    public void validateResult(String payload) throws Throwable {
        new Producer(kafkaConfiguration).produceMessage(payload);
    }

and on feature use

Then Notify kafka with payload "{example:value}"

I want to do that because I want to reuse that code on base project in order to be included in other project If annotation doesn't works, maybe you can suggest me another way to do it


Solution

  • The answer is simple, use normal Java / Maven concepts. Move the common Java code to the "main" packages (src/main/java). Now all you need to do is build a JAR and add it as a dependency to any Karate project.

    The last piece of the puzzle is this: use the classpath: prefix to refer to any features or JS files in the JAR. Karate will be able to pick them up.

    EDIT: Sorry Karate does not support Cucumber or step-definitions. It has a much simpler approach. Please read this for details: https://github.com/intuit/karate/issues/398