Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add samples to show using Flogger in JUnit #170

Open
anantdamle opened this issue Jun 19, 2020 · 3 comments
Open

Add samples to show using Flogger in JUnit #170

anantdamle opened this issue Jun 19, 2020 · 3 comments
Labels
P4 type=documentation Documentation that is other than for an API

Comments

@anantdamle
Copy link

anantdamle commented Jun 19, 2020

As part of unit testing, it becomes important to test the Logged messages in case of exceptions or other such scenarios.

Is this the recommended way to test logging behaviour in tests?

 @Test
  public void read_invalidPath_logsError() {
    Handler mockHandler = Mockito.mock(Handler.class);
    ArgumentCaptor<LogRecord> logRecordCaptor = ArgumentCaptor.forClass(LogRecord.class);
    //set mock handler with Argument Captor
    Logger.getLogger(JsonMessageParser.class.getName()).addHandler(mockHandler);

    JsonMessageParser.of(TEST_JSON).read("$.code2");

    verify(mockHandler).publish(logRecordCaptor.capture());

    assertThat(logRecordCaptor.getValue().getMessage()).contains("error reading [$.code2]");
  }
@hagbard
Copy link
Contributor

hagbard commented Jun 19, 2020

If you know the backend you're using, you can just test using the backend's idiomatic approach.
E.g. for JUL, just install a test log handler to capture the records and then assert on them.

I wouldn't think you'd need to do any mocking here though.

@anantdamle
Copy link
Author

I was using that technique and It works when the loggers are not rate-limited

The LoggerBackend does not get the logData in the following case, if there are more than one failing Test-cases.
The following unit-test becomes flaky, it sometimes works and fails other times.

e.g. If the call site is

private static final logger = FluentLogger.forEnclosingClass();
...
public String processedItem() {
    try{
        return processItem();
    } catch (ProcessingException exception) {
        logger.atInfo().atMostEvery(1, TimeUnit.MINUTE).withCause(exception).log("item %s was not processed");
       return null;
    }
}

Unit Tests as follows
The assertion on logger does not work consistently.

@Test
public void processedItem_failureCase_null() {
  assertThat(processedItem()).isNull();
}

@Test
public void processedItem_failureCase2_null() {
    Handler mockHandler = Mockito.mock(Handler.class);
    ArgumentCaptor<LogRecord> logRecordCaptor = ArgumentCaptor.forClass(LogRecord.class);
    //set mock handler with Argument Captor
    Logger.getLogger(JsonMessageParser.class.getName()).addHandler(mockHandler);

    // Method under test
    processedItem()    

    verify(mockHandler).publish(logRecordCaptor.capture());
    assertThat(logRecordCaptor.getValue().getMessage()).contains("item %s was not processed");
}

@hagbard
Copy link
Contributor

hagbard commented Jun 19, 2020

Ahh yes, the right way to do that is using the GrpcScopedLoggingContext which sadly I don't think is open-sourced yet.

Basically if your Platform instance returns true for "shouldForceLogging" then everything will work, but the "nice" mechanism for that is using this GrpcScopedLoggingContext thing and that's not pushed yet (the code is pretty much done though, so I will see about getting it out soon).

Once that's there it's easy to make a JUnit rule which install a context for the duration of a test which forces all logging to happen.

Sorry to not have a better answer for you :(

@kluever kluever added P4 type=documentation Documentation that is other than for an API labels Jun 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P4 type=documentation Documentation that is other than for an API
Projects
None yet
Development

No branches or pull requests

3 participants