quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.65k stars 2.64k forks source link

Conditionally use @Mock #5394

Closed edewit closed 2 years ago

edewit commented 4 years ago

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.

ia3andy commented 4 years ago

Having a way to manage how mocks are used from a test is a must have IMHO

InfoSec812 commented 4 years ago

+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.

InfoSec812 commented 4 years ago

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.

ia3andy commented 4 years ago

@geoand any hint on how that could be achievable, I would be interested in implementing it :)

geoand commented 4 years ago

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...

jordanglassman commented 4 years ago

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.

geoand commented 4 years ago

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

InfoSec812 commented 4 years ago

@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();
geoand commented 4 years ago

Yes I am.

I am not sure I follow what you mean about Kafka Streams.

InfoSec812 commented 4 years ago

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.

geoand commented 4 years ago

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

FroMage commented 4 years ago

Well, are we generating those kafka classes? Where are they defined or coming from? Do we own that code?

geoand commented 2 years ago

Between DevServices and TestProfile I think we have covered this use case, so I will close this