Насмешливый / фальшивый статический финальный атрибут

У меня есть класс RequireJavaVersion, который я хочу написать тесты, для которых выглядит так:

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 );

Кроме того, у меня есть класс SystemUtils, который выглядит так:

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

Поэтому я хочу написать такой тест (используя 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 );

Таким образом, проблема на данный момент заключается в том, что, похоже, класс SystemUtils инициализируется один раз, а потом уже нет... и дальнейшие тесты не пройдут...(или я что-то ошибаюсь).

Так что в настоящий момент я не уверен, пойду ли я в неправильном направлении. Класс Fake будет подделывать только метод getProperty..method, но вопрос в следующем: это правильный подход или мне нужно пойти в другом направлении и вместо этого попытаться подделать последний статический атрибут? У кого-то есть идея или намек?

1 ответ

После копания в деталях и подсказки @tsolakp я нашел решение:

Теперь я могу установить результат для public static final String JAVA_VERSION более или менее просто проверить остальную часть кода.

@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 );
    }

Это также работает в сочетании с правилами JUnit.

Другие вопросы по тегам