简体   繁体   中英

Mocking / Faking static final attribute

I have a class RequireJavaVersion which I want to write tests for which looks like this:

public void execute( EnforcerRuleHelper helper )
     throws EnforcerRuleException
 {
    String javaVersion = SystemUtils.JAVA_VERSION;
    Log log = helper.getLog();

    log.debug( "Detected Java String: '" + javaVersion + "'" );
    javaVersion = normalizeJDKVersion( javaVersion );

Furthermore I have the class SystemUtils which looks like this:

public static final String JAVA_VERSION = getSystemProperty("java.version");

So I want to write a test like this(using JMockit):

@Rule
public ExpectedException exception = ExpectedException.none();

public static class FakeSystemUtils extends MockUp<SystemUtils> {
    private final String fakedVersion;
    public FakeSystemUtils(String version)
    {
        this.fakedVersion = version;
    }
    @Mock
    private final String getSystemProperty(final String property) {
      return this.fakedVersion;
  }    
};
..

new FakeSystemUtils( "1.4" );

rule = new RequireJavaVersion();
rule.setVersion( "1.5" );

exception.expect( EnforcerRuleException.class );
exception.expectMessage( "Detected JDK Version: 1.4 is not in the allowed range 1.5." );
rule.execute( helper );

So the problem at the moment is that it looks like the SystemUtils class seems to be initialised a single time and afterwards not anymore..and further tests will fail...(Or I'm mistaken something).

So I'm not sure at the moment if I'm going into wrong direction. The Fake class will only fake the getProperty..method but the question is: Is this the correct approach or do I need to go into different direction and try to fake the final static attribute instead? Does someone has an idea or hint?

After digging into the details and the hint of @tsolakp I found a solution:

Now I can set the result for the public static final String JAVA_VERSION more or less simple to check the rest of the code.

@RunWith( PowerMockRunner.class )
@PrepareForTest( { SystemUtils.class } )
public class RequireJavaVesionTest
{
   ...
    @Test
    public void first()
        throws EnforcerRuleException
    {
        Whitebox.setInternalState( SystemUtils.class, "JAVA_VERSION", "1.4" );

        rule = new RequireJavaVersion();
        rule.setVersion( "1.5" );

        exception.expect( EnforcerRuleException.class );
        exception.expectMessage( "Detected JDK Version: 1.4 is not in the allowed range 1.5." );
        rule.execute( helper );
    }

This also works in combination with JUnit rules.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM