8

Im trying to test a Spring Boot 2.3 @Controller that does metrics via Actuator/Prometheus with @WebMvcTest. Unfortunately this fails with a NPE, probably because the Micrometer/Prometheus classes are not present in test.

The controller does

Counter.builder(COUNTER_STATUS)
        .description(DESCRIPTION_STATUS)
        .tags(TAG_ACCOUNT, String.valueOf(accountId), TAG_STATUS, String.valueOf(status))
        .register(registry)
        .increment();

The test has

@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
@WebMvcTest(HerodotusController.class)

  @MockBean(MeterRegistry.class)
  private MeterRegistry meterRegistry;

This fails with an NPE at the line of Counter...; I believe because at test runtime there's no implementation of that interface (at runtime it's implemented by io.micrometer:micrometer-registry-prometheus).

How can I get an implementation of the Micrometer interface into my test so that it passes?

Martin Schröder
  • 4,176
  • 7
  • 47
  • 81

1 Answers1

35

The problem is the mocked MeterRegistry.

The NPE happens here:

public Counter register(MeterRegistry registry) {
  return registry.counter(new Meter.Id(name, tags, baseUnit, description, Type.COUNTER));
}

The solution is to not mock the MeterRegistry but instead provide one via

@TestConfiguration
static class AdditionalConfig {
  @Bean
  public MeterRegistry registry() {
    return new SimpleMeterRegistry();
  }
}
Martin Schröder
  • 4,176
  • 7
  • 47
  • 81