2010-05-21 38 views
23

Ai đó có thể cho tôi biết tại sao assertSame() không thực hiện được khi tôi sử dụng giá trị> 127?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! 
     } 

Tôi đang sử dụng JUnit 4.8.1.

+3

Bạn chỉ nên sử dụng 'assertSame' để kiểm tra bình đẳng tham chiếu - ví dụ:' a == b'. Đối với sự bình đẳng, bạn nên sử dụng 'assertEquals'. –

Trả lời

44

Lý do là hộp tự động của Java. Bạn sử dụng phương pháp:

public static void assertSame(Object expected, Object actual) 

Nó chỉ hoạt động với Đối tượng. Khi bạn vượt qua int giây cho phương pháp này, Java sẽ tự động gọi

Integer.valueOf(int i) 

với các giá trị này. Vì vậy, các diễn viên để int không có hiệu lực.

Đối với các giá trị nhỏ hơn 128 Java có bộ nhớ cache, do đó, assertSame() so sánh đối tượng Integer với chính nó. Đối với các giá trị lớn hơn 127, Java tạo các phiên bản mới, do đó, assertSame() so sánh đối tượng Integer với một đối tượng khác. Vì chúng không giống nhau, phương thức assertSame() trả về false.

Bạn nên sử dụng phương pháp này:

public static void assertEquals(Object expected, Object actual) 

để thay thế. Phương pháp này sử dụng phương pháp equals() từ Object.

+0

Bạn đúng là JVM * phải * cache -128..127, nhưng đối với các giá trị nằm ngoài phạm vi đó, điều đó hoàn toàn phụ thuộc vào việc thực hiện JVM phạm vi mà nó lưu trữ, \t _ "Ít triển khai bộ nhớ hạn chế hơn, ví dụ , cache tất cả các giá trị char và short, cũng như các giá trị int và long trong phạm vi từ -32K đến + 32K. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5 .html # jls-5.1.7 qua https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127/20948389#20948389 – weston

12

assertSame có hai đối số Object và do đó trình biên dịch phải tự động hóa các chữ số int của bạn thành Integer.

này tương đương với

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

Bây giờ cho các giá trị giữa -128 và 127, JVM sẽ cache kết quả của Integer.valueOf, vì vậy bạn nhận được cùng một Integer đối tượng trở lại mỗi lần. Đối với các giá trị nằm ngoài phạm vi đó, bạn sẽ lấy lại các đối tượng mới.

Vì vậy, đối với assertSame(127, 127), JUnit đang so sánh cùng một đối tượng, do đó nó hoạt động. Đối với assertSame(128, 128), bạn nhận được các đối tượng khác nhau, do đó, nó không thành công.

Một lý do khác để cẩn thận với tính năng tự động.

+0

Bạn đúng rằng JVM phải cache -128..127, nhưng đối với các giá trị nằm ngoài phạm vi đó, điều đó hoàn toàn phụ thuộc vào việc thực hiện JVM phạm vi lưu trữ, _ "Việc triển khai ít bộ nhớ hơn, ví dụ, cache tất cả các giá trị char và short, cũng như giá trị int và dài trong phạm vi từ -32K đến + 32K. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 thông qua https://stackoverflow.com/a/20948389/360211 – weston