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

Verifying SLF4J logging passes for 1.33, fails for 1.34+ #507

Closed
Thunderforge opened this issue Mar 2, 2018 · 1 comment
Closed

Verifying SLF4J logging passes for 1.33, fails for 1.34+ #507

Thunderforge opened this issue Mar 2, 2018 · 1 comment
Assignees
Labels

Comments

@Thunderforge
Copy link

@Thunderforge Thunderforge commented Mar 2, 2018

Library versions

  • JMockit: 1.33, 1.34 through 1.38
  • JUnit: 4.12
  • SLF4J : slf4j-api:1.7.25, slf4j-log4j12:1.7.25

Description of the problem

Consider the following code, which uses an SLF4J Logger:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);

    public void logErrorMessage(String message) {
        LOGGER.error(message);
    }
}

This is unit tested like so, following the instructions on this StackOverflow post:

import mockit.Capturing;
import mockit.Tested;
import mockit.Verifications;
import org.junit.Test;
import org.slf4j.Logger;

public class MyClassTest {

    @Tested
    private MyClass myClass;

    @Capturing
    private Logger logger;

    @Test
    public void logErrorMessageSuccessful() {
        final String message = "Foo";
        myClass.logErrorMessage(message);

        new Verifications() {{
            logger.error(message);
        }};
    }
}

With JMockit 1.33, this unit test passes. With JMockit 1.34 and later, it fails with the following error:

Missing invocation to:
org.slf4j.Logger#error("Foo")
   on mock instance: org.slf4j.$Impl_Logger@2690d8e4
	at MyClassTest$1.<init>(MyClassTest.java:26)
	at MyClassTest.logErrorMessageSuccessful(MyClassTest.java:25)

This is reproducible 100% time on every version up to 1.38 (the latest at the time of this writing).

The issues fixed according to the 1.34 changelog don't seem to be relevant to this problem, but it does include this item:

  • Improved @Capturing performance.

Is it possible that a regression was introduced as a result of those performance improvements?

@Thunderforge

This comment has been minimized.

Copy link
Author

@Thunderforge Thunderforge commented Mar 2, 2018

Did some more investigating and found that this only seems to happen if slf4j-log4j12 is on the classpath. If you use do not have it (thus having SLF4J rely on the no-operation logger implementation) it passes.

Here is the Gradle dependency list I used for the code above:

dependencies {
    compile "org.slf4j:slf4j-api:1.7.25"
    compile "org.slf4j:slf4j-log4j12:1.7.25"
    testCompile "org.jmockit:jmockit:1.38"
    testCompile "junit:junit:4.12"
}

Commenting out the second line causes MyClassTest to pass on JMockit 1.34 through 1.38, but of course results in this error because no logging library is loaded.

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

I used an empty log4j.properties file when reproducing this error with slf4j-log4j12 loaded.

@rliesenfeld rliesenfeld self-assigned this Mar 5, 2018
@jmockit jmockit locked and limited conversation to collaborators Jul 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
2 participants
You can’t perform that action at this time.