简体   繁体   中英

How to use the output binding of spring-cloud-stream in unit tests?

I'm using spring cloud stream to modify a Kafka Topic and write the resulting data with ".toTable()" to a table. In the application.yaml I will set the input and output bindings. This works fine on the Kafka cluster but not with my current test setup.

@Configuration
public class ObjectTopology {

    @Bean
    public static Serde<Object> objSerde() {
        return new ProtobufSerde<>(Object.parser());
    }

    @Bean
    public Function<KStream<String, Object>, KTable<String, Object>> obj() {

        return objKStream -> objKStream
                .transform((TransformerSupplier<String, Object, KeyValue<String, Object>>) SomeTransformer::new)
                .toTable();
    }
}

application.yaml:

spring.cloud.stream.bindings:
    obj-in-0:
        destination: input-name
    obj-out-0:
        destination: output-name

How would I access the KTable generated by "toTable" in the code below? Is there a way to use the spring-cloud-stream bindings in my unit tests?

ObjectTopology objectTopology = new ObjectTopology();
StreamsBuilder streamsBuilder = new StreamsBuilder();

Serde<String> keySerde = Serdes.String();
Serde<Object> valueSerde = objSerde();

KStream<String, Object> objKStream = streamsBuilder.stream("input-topic-name", Consumed.with(keySerde, valueSerde));

objectTopology.obj().apply(objKStream);

TopologyTestDriver topologyTestDriver = new TopologyTestDriver(streamsBuilder.build());

TestInputTopic<String, Object> objTestInputTopic = topologyTestDriver.createInputTopic("input-topic-name", keySerde.serializer(), valueSerde.serializer());
KeyValueStore<String, Object> objStore = topologyTestDriver.getKeyValueStore("???"); // I would like to use the name defined by the output binding in application.yaml "output-name"

Object object = createObject();

objTestInputTopic.pipeInput("elem_0", object);

Object result = objStore.get("elem_0");
assertThat(result).isEqualTo(object);

To access the KTable generated by the toTable method in your unit test, you can use the TopologyTestDriver 's getKeyValueStore method to retrieve the store associated with the output binding.

In your code, you can use the getKeyValueStore method like this:

TopologyTestDriver topologyTestDriver = new TopologyTestDriver(streamsBuilder.build());
KeyValueStore<String, Object> objStore = topologyTestDriver.getKeyValueStore("output-name");

This will retrieve the store associated with the output binding defined in your application.yaml file, which you can then use to access the values in the KTable .

Alternatively, you can use the @Output annotation to inject the output binding's MessageChannel into your test, and then use the send method to send messages to the output binding. You can then use the TopologyTestDriver 's createInputTopic method to create a test input topic that represents the output binding, and use this input topic to verify that the messages were sent tothe output binding as expected.

Here's an example of how you might use the @Output annotation in your test:

@Autowired
@Output("obj-out-0")
private MessageChannel outputChannel;

@Test
public void testOutputBinding() {
    // create a message to send to the output binding
    Message<Object> message = MessageBuilder.withPayload(createObject()).build();

    // send the message to the output binding
    outputChannel.send(message);

    // create a test input topic representing the output binding
    TestInputTopic<String, Object> objTestInputTopic = topologyTestDriver.createInputTopic("obj-out-0", keySerde.serializer(), valueSerde.serializer());

    // verify that the message was sent to the output binding
    assertThat(objTestInputTopic.readKeyValue()).isEqualTo(new KeyValue<>("elem_0", createObject()));
}

toTable creates an internal topic. You should probably use topologyTestDriver.createOutputTopic to read it.

For the naming, there is https://kafka.apache.org/26/javadoc/org/apache/kafka/streams/kstream/KStream.html#toTable--

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM