Search code examples
javaspring-bootunit-testingjunitmockito

I have a spring boot unit tests code that builds a Timer using method chaining, how can I handle/bypass that during the test?


The class under test contains the following method:

protected void recordRepositoryInvocationMetrics(Method method, Object target, long queryDuration) {
    Timer.builder("mysql.call.duration")
         .description("MySqL Database call Duration")
         .tag("method.name", target.getClass().getSimpleName() + "." + method.getName())
         .tag("service.name", context.getId() != null ? context.getId() : "unknown")
         .register(meterRegistry)
         .record(queryDuration, TimeUnit.MILLISECONDS);
}

It's causing me no end of headaches trying to get this test to work.
How can I bypass/handle this method?
Can I restructure this code in such a way that makes it easier to mock perhaps?


Solution

  • The solution is to use a "partial mock" by adding the @Spy annotation to the class under test like so:

    @InjectMocks
    @Spy
    private RepositoryMetricsInvocationAspect aspect;
    

    Then in the test I can do this:

    doNothing().when(aspect).recordRepositoryInvocationMetrics(any(Method.class), any(Object.class), anyLong()); 
    

    The method will still be called, but the code within it won't be executed. This allows me to test the logic of the class without executing the static Timer methods.