2016-05-16 5 views
0

У меня возникло затруднительное время, издеваясь над приватным статическим финальным строковым полем в классе. Вот мой Java пример кода:Mock private static final String using Mockito

public class Fruit { 
private static final String FRUIT = "apple"; 

public void getFruit() { 
    System.out.println("I like " + FRUIT); 
} 

}

И я Mockito издеваться переменную ФРУКТЫ, так что я могу изменить значение ФРУКТЫ от «яблока» в «манго». Для этого вот мой тест:

public class FruitTest { 
@Test 
public void testFruit() throws NoSuchFieldException, SecurityException, Exception { 
    setFinalStatic(Fruit.class.getDeclaredField("FRUIT"), "mango"); 
    Fruit fruit = new Fruit(); 
    fruit.getFruit(); 
} 

static void setFinalStatic(Field field, Object newValue) throws Exception { 
    field.setAccessible(true); 
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
    field.set(null, newValue); 
} 

}

я ожидал, когда я System.out.println("I like " + FRUIT); он будет печатать манго, но все же печатает яблоко. Я был бы очень признателен, если кто-нибудь сможет мне помочь с этим ТОЛЬКО ИСПОЛЬЗОВАТЬ MOCKITO, а не PowerMock и т. Д.

+2

Поведение класса «Фрукт» будет всегда возвращать «яблоко». Поэтому я не думаю, что вы должны изменить это. Если вы хотите, чтобы возвращали переменный тип фруктов, не делайте поле 'static final' и используйте' when() ', чтобы высмеять нужное поведение. –

ответ

0

Константы времени компиляции могут быть встроены в javac для оптимизации. Если вы измените свой класс Fruit примерно так:

общественный статический класс Fruit { public static final String FRUIT = getFruit();

public static String getFruit() { 
     return "apple"; 
    } 



} 

Он покажет результат манго с setFinalStatic (Fruit.class.getField ("Фрукты"), "манго"); System.out.println (Fruit.FRUIT);

0

Недавно я искал некоторые статические поля, и я не думаю, что вы можете делать то, что вы пытаетесь, без помощи powermock. Я также не уверен, зачем вам это нужно. Частное статическое конечное поле является константой, и не должно быть реальной причины, по которой вы хотите, чтобы константа менялась. Любой тест, пытающийся сделать это, пытается проверить неправильную вещь.

0

Изменение значения константы не является хорошей практикой. Более того, я думаю, что это невозможно. Однако, если вы хотите изменить значение поля, удалите модификатор `final.

0

Слово final описывает именно то, что вы не должны изменять это значение после создания String. Так вы получаете константы в Java. Метод getFruit всегда будет возвращать «яблоко». Мокито не поможет вам в этом. Если вы тестируете этот метод, вам нужно проверить, что он всегда возвращает «яблоко». И в вашем случае не имеет значения, является ли метод статическим или нет, поскольку возвращаемое вами значение является постоянным. Использование рефлексии - не очень хорошая идея, а не только потому, что это очень плохая практика кодирования, но также и потому, что у вас нет способа правильно управлять изменениями в будущем. Это такой инвазивный код, который требует огромного количества обслуживания, и он всегда генерирует несколько строк, чтобы заставить этот метод изменять во время выполнения, чтобы он «мог быть протестирован». Во всех случаях реальной жизни не требуется отражения в модульных тестах, если, конечно, для этого нет веских оснований или просто для того, чтобы архитектура нуждалась в улучшении. Отражение - это скорее научная вещь, или если вы строите свою собственную систему инъекций, насмешливый инструмент или все, что требует такого рода кодирования.