Closed edewit closed 2 years ago
Having a way to manage how mocks are used from a test is a must have IMHO
+1 The testing story around Quarkus is one of the biggest issues I am having with the tools right now. For example, to test an application which integrates Kafka, I need to have a Kafka instance to connect to. This is similar for many other ancillary service (ActiveMQ, Infinispan, etc...). For a good developer story, being able to test locally without ancillary services is going to be a necessity.
It has been suggested to me to use TestContainers, but that requires that I write additional logic into my tests to detect when I am running tests locally versus running in a CI/CD pipeline inside of a Kubernetes cluster.
@geoand any hint on how that could be achievable, I would be interested in implementing it :)
This is a hard problem to solve currently... I was actually thinking about it a little and didn't come up with any easy solutions...
My current workaround for this is to comment out @Mock
on the undesired mock while doing development and then @Ignore
the tests before checking in.
Sounds like "disabling" annotations involves mucking around in bytecode or various other overcomplicated schemes.
Quarkus 1.4 will contain major improvements in this area.
Please see the testing documentation in this repository if you wish to know more before 1.4 is released
@geoand Are you referring to QuarkusMock? That still will not address issues like Kafka Streams where you are required to use a static method on a class.
Example:
StreamsBuilder builder = new StreamsBuilder();
// Set up JSON-B Serializers/Deserializers for use with Kafka Streams
JsonbSerde<VehicleEvent> eventSerde = new JsonbSerde<>(VehicleEvent.class);
JsonbSerde<VehicleStatus> statusSerde = new JsonbSerde<>(VehicleStatus.class);
// Instantiate a Time Windowed ByteStoreSupplier
WindowBytesStoreSupplier storeSupplier = Stores.persistentWindowStore(stateStore, Duration.of(2, MINUTES), WINDOW_DURATION, false);
// Implement stream, read from eventsTopic, aggregate on the time window, and publish results to statusTopic
builder.stream(eventsTopic, Consumed.with(Serdes.String(), eventSerde))
.groupByKey()
.windowedBy(AGGREGATE_WINDOW)
.aggregate(
VehicleStatus::new, // At the start of a new Window, create an instance of the VehicleStatus object
(key, value, aggregate) -> this.updateAggregate(aggregate, value), // Stateless method on the VehicleStatus is called to aggregate data
Materialized.<String, VehicleStatus>as(storeSupplier) // Materialize the stream using Serdes
.withKeySerde(Serdes.String())
.withValueSerde(statusSerde)
)
.suppress(Suppressed.untilWindowCloses(unbounded())) // Suppress output to the statusTopic until the end of the time window
.toStream()
.peek((vehicleId, status) -> persistQueue.send(status)) // Publish aggregated data to persist queue for storage to DB
.peek((vehicleId, status) -> LOG.warn("Status Event: {}: {}", vehicleId.key(), status.getAvg())) // Log aggregated status
.to(statusTopic, Produced.with(WindowedSerdes.timeWindowedSerdeFrom(String.class), statusSerde)); // Publish aggregated data
return builder.build();
Yes I am.
I am not sure I follow what you mean about Kafka Streams.
See my updated comment above... The issue is that a lot of these classes require you to call static methods on them which would not be "mock"able.
We might be able to do something about those in the future. @FroMage has a PR where he adds support for mocking Panache static methods
Well, are we generating those kafka classes? Where are they defined or coming from? Do we own that code?
Between DevServices and TestProfile I think we have covered this use case, so I will close this
Description Testing my rest endpoint I like the way I can create a mock for my service and only test how my parameter are parsed and passed to the service. But I also have a test that tests the service, in that case I want the real service not the mock. It would be great if there was a way to use the mock conditionally.