Micrometer Unit Test Java
Asked Answered
E

2

5

I have created a Micrometer class where counters are created and incremented. How to write unit test cases for the public method and avoid registering or sending the events to micrometer.

public class MicroMeter {
private static final MeterRegistry registry = Metrics.globalRegistry;
private Counter createCounter(final String meterName, Map<String, String> mp) {

    List<Tag> tags = new ArrayList<>();
    for (Map.Entry<String, String> entry : mp.entrySet()) {
        tags.add(Tag.of(entry.getKey(), entry.getValue()));
    }
    return Counter
            .builder(meterName)
            .tags(tags)
            .register(registry);
}

private void incrementCounter(Counter counter)  {
        counter.increment();
}

public static void createCounterAndIncrement(final String meterName, Map<String, String> mp){
    MicroMeter microMeter = new MicroMeter();
    Counter counter = microMeter.createCounter(meterName, dimensions);
    microMeter.incrementCounter(counter);
}

}

Earwax answered 20/10, 2022 at 16:54 Comment(0)
B
11

One way of writing a test for this scenario is to utilize the SimpleMeterRegistry by adding it to the globalRegistry, fetch the Counter and then test the expected behaviour.

Example snippet:

private MeterRegistry meterRegistry;

@BeforeEach
void setUp() {
  meterRegistry = new SimpleMeterRegistry();
  Metrics.globalRegistry.add(meterRegistry);
}

@AfterEach
void tearDown() {
  meterRegistry.clear();
  Metrics.globalRegistry.clear();
}

@Test
void testCreateCounterAndIncrement() {
  // When
  MicroMeter.createCounterAndIncrement("meterName", Map.of("key", "val"));

  // Then
  var counter = meterRegistry.find("meterName").counter();
  then(counter).isNotNull();
  then(counter.count()).isEqualTo(1);
  then(counter.getId().getTag("key")).isEqualTo("val");
 }
Blondellblondelle answered 24/10, 2022 at 14:22 Comment(2)
Where is then coming from?Cavuoto
@Cavuoto most likely from AssertJLunula
M
2

You can simply pass in an in-memory meter registry for unit testing. I don’t remember the class name, but Micrometer comes with one. Your code needs to be designed to accept the registry, not create it.

Because the whole purpose of Micrometer is to integrate with your chosen backend (like Graphite), there aren’t a lot of benefits to be had purely from unit testing. Apart of just creating the metrics, you need to check that those are linearized if your backend doesn’t support tags, and other things like client-side histograms if those are enabled. What I do myself and recommend is integration testing. Here are the general steps:

  1. Create an in-memory meter registry; The registry should be a bean, not a static variable, and you can replace it for testing very easily.
  2. Mock the sender for your backend, like GraphiteSender if I remember the name correctly, and use the mock to verify that metrics being sent.
Mauricemauricio answered 20/10, 2022 at 17:7 Comment(1)
Not sure if it is the class you are talking about, but in my units I pass SimpleMeterRegistry, which comes with a micrometer.Loudermilk

© 2022 - 2024 — McMap. All rights reserved.