Reputation: 83
I have implemented Micrometer Prometheus counter in my service by injecting MeterRegistry
and incrementing the count as shown below, and I have written a test case as well, but when I am running the test case, I am getting:
"java.lang.NullPointerException: Cannot invoke "io.micrometer.core.instrument.MeterRegistry.counter(String, String[])" because "this.meterRegistry" is null".
Service file:
@Autowired
private MeterRegistry meterRegistry;
public void counterIncrement() {
meterRegistry.counter("test_count").increment();
}
Test case file:
@MockBean
private MeterRegistry registry;
@Test
void testCounter() {
// invoking counterIncrement();
}
Upvotes: 4
Views: 15225
Reputation: 158
You can test metrics without Mockito using SimpleMeterRegistry
@Test
void testCounter() {
var meterRegistry = new SimpleMeterRegistry();
Metrics.addRegistry(meterRegistry);
// invoke counterIncrement();
var actual = meterRegistry.counter("test_count").count();
assertEquals(1.0d, actual);
}
Upvotes: 8
Reputation: 687
How do you create your class under test?
Since the registry
is never instantiated, something seems up with how you setup your test.
Check that you are using the @MockBean
in the correct way. This will replace the bean in the application context and if you do not spin up a spring context in your test, it will not work. See this post for more info.
A different approach would be to use @Mock
and inject the registry in the constructor, example:
@ExtendWith(MockitoExtension.class)
public class MyServiceTest {
@Mock
private MeterRegistry registry;
private MyService myService;
@BeforeEach
void setup() {
myService = new MyService(registry);
}
@Test
void testCounter() {
var counter = mock(Counter.class);
given(registry.counter(any(String.class))).willReturn(counter);
myService.counterIncrement();
}
Upvotes: 2
Reputation: 846
Depending on the test and the service there are several ways to deal with the missing MeterRegistry.
@BeforeEach
as suggested by @checketts in the comments.@Component
with an autowired MeterRegistry and some public getter for the factory.I favour solution 3 but would use solution 1 whenever appropriate. I've added solutions 4 and 5 just because there might be some additional reasons and special cases that make these solutions a good choice. If so, I prefer 4 over 5.
Upvotes: 0
Reputation: 1536
Depending on which junit version you are using you need to add the annotation to your test class. Junit 5: @ExtendWith(MockitoExtension.class)
or for Junit 4: @RunWith(MockitoJUnitRunner.class)
Upvotes: 0