Reputation: 321
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
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
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
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