2010-05-21 2 views
23

값> 127을 사용할 때 assertSame()이 실패하는 이유는 누구에게 말해 줄 수 있습니까?JUnit - assertSame

 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을 사용하고 있습니다.

+3

'assertSame'은 참조 평등 검사 (예 :'a == b')에만 사용해야합니다. 평등을 위해서'assertEquals'를 사용해야합니다. –

답변

44

그 이유는 자바의 autoboxing입니다. 다음과 같은 방법을 사용하십시오.

public static void assertSame(Object expected, Object actual) 

오브젝트에서만 작동합니다. 이 방법에 int의를 통과하면, 자바는 자동으로이 값

Integer.valueOf(int i) 

를 호출합니다. 따라서 int에 대한 캐스트는 아무 효과가 없습니다.

값이 128 미만인 경우 Java는 캐시를 가지고 있으므로 assertSame()Integer 개체를 자체와 비교합니다. 127보다 큰 값의 경우 Java는 새 인스턴스를 작성하므로 assertSame()Integer 오브젝트를 다른 인스턴스와 비교합니다. 동일한 인스턴스가 아니기 때문에 assertSame() 메서드는 false를 반환합니다. 대신

public static void assertEquals(Object expected, Object actual) 

:

당신은 방법을 사용한다. 이 방법은 Objectequals() 방법을 사용합니다.

+0

JVM * must * cache -128..127이 맞지만 그 범위를 벗어나는 값은 캐시 범위 내에서 JVM 구현에 따라 달라집니다. \t _ "예를 들어 메모리 제한이 적은 구현 예 모든 char 및 short 값은 물론 int 및 long 값을 -32K에서 + 32K 범위에서 캐시합니다. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5 .html # jls-5.1.7 https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127/20948389#20948389 – weston

12

assertSame은 두 개의 Object 인수를 취하므로 컴파일러는 리터럴을 Integer에 자동 저장해야합니다. 다시 같은 Integer 개체마다 얻을 수 있도록

이 -128 ~ 127 사이의 값을 이제

assertSame(Integer.valueOf(128), Integer.valueOf(128)); 

에 해당 JVM은, Integer.valueOf의 결과를 캐시합니다. 해당 범위를 벗어난 값의 경우 새로운 객체를 다시 가져옵니다.

따라서 assertSame(127, 127)의 경우 JUnit은 동일한 객체를 비교하므로 작동합니다. assertSame(128, 128)의 경우 다른 개체가 생겨 실패합니다.

오토 박싱에주의해야하는 또 다른 이유.

+0

귀하가 맞습니다. JVM은 -128..127을 캐시해야하지만 그 범위를 벗어나는 값은 캐시 범위에 따라 JVM 구현에 달려 있습니다 _ 예를 들어 메모리 제한 구현이 적어지면 모든 char 및 short 값을 캐시 할 수 있습니다. -32K에서 + 32K 범위의 int 및 long 값도 포함됩니다. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 ~을 통해 https://stackoverflow.com/a/20948389/360211 – weston