JUnit - assertSame
Может ли кто-нибудь сказать мне, почему assertSame() не работает, когда я использую значения > 127?
import static org.junit.Assert.*;
...
@Test
public void StationTest1() {
..
assertSame(4, 4); // OK
assertSame(10, 10); // OK
assertSame(100, 100); // OK
assertSame(127, 127); // OK
assertSame(128, 128); // raises an junit.framework.AssertionFailedError!
assertSame(((int) 128),((int) 128)); // also junit.framework.AssertionFailedError!
}
Я использую JUnit 4.8.1.
Ответы
Ответ 1
Причиной является автобоксирование Java.
Вы используете метод:
public static void assertSame(Object expected, Object actual)
Он работает только с объектами. Когда вы передаете int
этому методу, Java автоматически вызывает
Integer.valueOf( int i )
с этими значениями. Поэтому приведение к int
не имеет эффекта.
Для значений менее 128 Java имеет кэш, поэтому assertSame()
сравнивает объект Integer
с самим собой. Для значений больше 127 Java создает новые экземпляры, поэтому assertSame()
сравнивает объект Integer
с другим. Поскольку они не являются одним и тем же экземпляром, метод assertSame()
возвращает false.
Вы должны использовать метод:
public static void assertEquals(Object expected, Object actual)
вместо этого. Этот метод использует метод equals()
из Object
.
Ответ 2
assertSame
принимает два аргумента Object
, поэтому компилятор должен автобоксать ваши литералы int
в Integer
.
Это эквивалентно
assertSame(Integer.valueOf(128), Integer.valueOf(128));
Теперь для значений от -128 до 127 JVM будет кэшировать результаты Integer.valueOf
, поэтому каждый раз возвращайте один и тот же объект Integer
. Для значений вне этого диапазона вы возвращаете новые объекты.
Итак, для assertSame(127, 127)
JUnit сравнивает одни и те же объекты, поэтому он работает. Для assertSame(128, 128)
вы получаете разные объекты, поэтому он терпит неудачу.
Еще одна причина быть осторожным с автобоксированием.