Adding NewRelic custom parameters to critical part of logging library. Hey I should add tests right to verify called correctly. wrote several tests to verify and ArgumentCaptor for NewRelic(), sometimes they work. Sometimes, they don't. Using intellij, gradle, SpringBoot(1.4.2).
compile group: 'com.newrelic.agent.java', name: 'newrelic-api', version: '3.26.1'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.6.5'
testCompile group: 'org.powermock', name: 'powermock-api-mockito', version: '1.6.5'
PROBLEM:
Randomly PowerMockito.mockStatic(NewRelic.class);
fails to capture arguments.
CODE
The tests use the following snippet:
@RunWith(PowerMockRunner.class)
@PrepareForTest({NewRelic.class})
public class NewRelicAddCustomParameterWrapperTest {
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(NewRelic.class);
PowerMockito.spy(NewRelic.class);
}
@Test
public void addCustomParam() throws Exception {
//GIVEN
String key = "woopsie-doo1";
String value = "tippyConue";
PowerMockito.spy(NewRelic.class);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> captor2 = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(NewRelic.class, "addCustomParameter", captor.capture(), captor2.capture());
//WHEN
newRelicAddCustomParameterWrapper.addCustomParam(key, value);
//THEN
String resourceKey = captor.getValue();
The 'NewRelicAddCustomParameterWrapper` class is simple method to wrap the NewRelic call:
public void addCustomParam(final String key, final String value) {
// Create a component to wrapper the static NewRelic
try {
NewRelic.addCustomParameter(key, value);
} catch (Exception newRCustomException) {
newRCustomException.printStackTrace();
}
}
what happens Symptomatic behavior:
- When run an individual test most of the time it works
- if run the ALL 5 tests group, PowerMockito ones Fail (Mockito-only tests pass)
- When run them Debug mode, putting a stop point anywhere, ALL PASS consistant
- When run debug mode, no breaks, random Fails like Run mode.
-- Error
No argument value was captured!
on this line of code:
String resourceKey = captor.getValue();
Error snippet from console:
You might have forgotten to use argument.capture() in verify()... ...or you used capture() in stubbing but stubbed method was not called. Be aware that it is recommended to use capture() only with verify()
Examples of correct argument capturing: ArgumentCaptor argument = ArgumentCaptor.forClass(Person.class); verify(mock).doSomething(argument.capture()); assertEquals("John", argument.getValue().getName());
org.mockito.exceptions.base.MockitoException: No argument value was captured! You might have forgotten to use argument.capture() in verify()... ...or you used capture() in stubbing but stubbed method was not called. Be aware that it is recommended to use capture() only with verify()
-- Thoughts & Questions:
- Tried adding
Thread.sleep(900)
everywhere to no avail. LOL :) - Debug doesn't help, cuz it works.
Is there a conflict between PowerMockito & Mockito?
Is PowerMock better PowerMockito: which should I be using?
- Debug Jump Into at .when method should be intercepted
MockGateway
does something like mocks method. - Re-run gradle
clean
on project - Is this class loading conflict between PowerMockito and Mockito? How to figure?
I spent way too much time on this. This is an important piece of code, need good testing coverage. Any thoughts, ideas, recommendations of how to proceed would be appreciated.
Simple sample project on github: CODE LINK: New Relic PowerMockito static unit test of NewRelic.addCustomParameter(key, value);