Fany Castro Vizoso
Fany Castro Vizoso

Reputation: 321

Spring boot 2.0.5.RELEASE - sleuth and mockito

I have tried to sort this out for a week, but no luck at all. The issue is with the unit tests.

This is the class that I am trying to test:

import brave.Span;
import brave.Tracer;

@Service
public class InternetBackEndRestClient {

    @Autowired
    private Tracer tracer;

  public PasswordJwtResponse generatePassworJwt(PasswordJwtRequest passwordJwtRequest, String traceId) throws LogonProxyException {
      log.info("{\"Starting method\": \"generatePassworJwt\", \"input\": {} }", passwordJwtRequest);

    Span newSpan = tracer.nextSpan().name("spanPasswordJwtResponse");
    ...
  }
}

How can I do the unit test? Brave.Tracer is a final class so that I cannot mock it. Is there anyway to set up a context? or mock Tracer?

@RunWith(MockitoJUnitRunner.class)
public class InternetBackEndRestClientTest {

   @InjectMocks
   private InternetBackEndRestClient internetBackEndRestClient; 

   @Mock
   private Tracer tracer; 

   @Test
   public void generatePassworJwt_test() { 
      internetBackEndRestClient.generatePassworJwt(...);
      ....
   }
}

Could anyone help me please?

Upvotes: 3

Views: 8921

Answers (3)

Matthew.Lothian
Matthew.Lothian

Reputation: 2082

You can manually set the span and trace id using TraceContext.newBuilder() in a test and past the Tracer into the class being tested.

Tracer tracer = Tracing.newBuilder().build().tracer();
TraceContext ctx = TraceContext.newBuilder().traceId(10L).spanId(10L).build();
Span span = tracer.toSpan(ctx);
tracer.withSpanInScope(span);

This might be a bit lighter than mocking the Tracer class

Upvotes: 3

Fany Castro Vizoso
Fany Castro Vizoso

Reputation: 321

Here is the solution that worked for me:

@RunWith(MockitoJUnitRunner.class)
public class InternetBackEndRestClientTest {

    private static final String TRACEID = "12345678901234567890123456789012";

    @InjectMocks
    private InternetBackEndRestClient internetBackEndRestClient;

    @Mock
    private Tracer tracer;
   @Mock
    private Span span;

    @Before
    public void setUp()  {

        MockitoAnnotations.initMocks(this);

        when(tracer.nextSpan()).thenReturn(span);
        when(tracer.nextSpan().name("spanPasswordJwtResponse"))
           .thenReturn(span);
        when(span.start()).thenReturn(span);

        Tracing tracing = Tracing.newBuilder().build();
        doReturn(tracing.tracer().withSpanInScope(span))
             .when(tracer).withSpanInScope(span);
        doNothing().when(span).finish();

        ...
    }
    ...
}

Upvotes: 7

Andy Wilkinson
Andy Wilkinson

Reputation: 116331

Your example isn't complete so it's hard to identify everything that's not quite right, but one thing is that @MockBean will only work if you're using Spring Boot testing's infrastructure. That means that you need to be using SpringRunner to run the test and you also have to have enabled @MockBean support. The most common way to do that is with @SpringBootTest:

@SpringBootTest
@RunWith(SpringRunner.class)
public class InternetBackEndRestClientTest {
    // …
}

You can read more about @MockBean in the Spring Boot reference documentation.

Upvotes: 0

Related Questions