2012-06-28 46 views
9

Tôi đã thử junit khẳng định hai đối tượng đôi với những điều sau đây:Junit chênh lệch giữa assertEquals (Double, Double) và assertEquals (double, double, đồng bằng)

Assert.assertEquals(Double expected, Double result); 

Đây là là tốt sau đó tôi quyết định thay đổi nó để sử dụng nguyên thủy đôi thay vì hóa ra là không được chấp nhận trừ khi bạn cũng cung cấp một delta.

vì vậy những gì tôi tự hỏi là sự khác biệt giữa việc sử dụng đối tượng Đôi hoặc kiểu nguyên thủy trong assertEquals này là gì? Tại sao sử dụng các đối tượng mà không có một đồng bằng ok nhưng sau đó sử dụng các nguyên thủy mà không có một đồng bằng không được chấp nhận? Java có đang thực hiện điều gì đó trong nền mà đã có một giá trị delta mặc định được tính đến không?

Cảm ơn.

Trả lời

12

There is NO assert method in JUnit với chữ ký

assertEquals(Double expected, Double result); 

Có một, tuy nhiên, chung cho các đối tượng:

assertEquals(Object expected, Object result); 

này gọi equals phương pháp đối tượng và như bạn có thể mong đợi, đó là không được khuyến khích sử dụng để so sánh các đối tượng Double. Để tăng gấp đôi, như bạn quan sát thấy, nó là hoàn toàn cần thiết để sử dụng một đồng bằng để so sánh, để tránh các vấn đề với làm tròn điểm nổi (giải thích đã có trong một số câu trả lời khác). Nếu bạn sử dụng phiên bản 3-đối số của assertEquals với double luận

assertEquals(double expected, double actual, double delta); 

Double của bạn sẽ nhận được âm thầm không có hộp bọc để double và tất cả mọi thứ sẽ hoạt động tốt (và xét nghiệm của bạn sẽ không thất bại bất ngờ :-).ghi cái gì đó

+1

+1 mở lại hộp thư, vâng, với báo trước rằng bạn sẽ có hành vi hơi khác một chút nếu một hoặc Đôi khác là rỗng. Với Object, bạn sẽ nhận được một thông điệp tốt đẹp, với delta, bạn sẽ nhận được một NullPointerException. –

+1

Trải nghiệm của tôi là các phương pháp này không hoạt động tốt cho các số rất lớn trong một số trường hợp, đặc biệt nếu dữ liệu của bạn thay đổi theo đơn đặt hàng của cường độ. Hai số có thể có một lỗi phần trăm rất nhỏ, nhưng yêu cầu một đồng bằng dường như lớn để phù hợp. Nhưng đồng bằng đó sẽ không hoạt động với nhiều giá trị nhỏ hơn trong dữ liệu của bạn. Trong một số trường hợp, ngay cả những con số rất lớn có thể được mong đợi để khớp với gần như tất cả các chữ số có nghĩa. Trong các trường hợp khác, chẳng hạn như khi so sánh hai thuật toán FFT được tối ưu hóa, điều đó ít có khả năng hơn nhiều. Một phương pháp mạnh mẽ hơn là hạn chế lỗi tương đối. – orodbhen

+0

@orodbhen Để làm cho nó hoạt động, ta nên tính toán delta dựa trên số mũ của giá trị mong đợi, vì vậy nếu 'double e' là giá trị mong đợi, thì delta phải là' double d = Math.pow (10, Math.log10 (Math. abs (e)) - 12), 'trong đó' 12' là số chữ số có nghĩa thực tế tối đa. Nếu bạn nhân log10 với giá trị <1.0, thì phép thử sẽ thất bại với 'e' có số mũ dương lớn và ngược lại, nếu bạn nhân log10 theo giá trị> 1.0, nó sẽ thất bại cho' e' có số mũ âm lớn - và đây là hiệu ứng bạn đang viết. Vì vậy, hãy đảm bảo delta phù hợp với số mũ của giá trị mong đợi. – Cromax

0

SOURCE. Giả sử rằng hai đôi hoặc phao nổi bằng với một vùng đồng bằng dương. Nếu không, AssertionError bị ném. Nếu giá trị kỳ vọng là vô cùng thì giá trị delta được bỏ qua.NaNs được coi là bằng nhau.

0

Tôi muốn nói rằng so sánh gấp đôi, nguyên thủy hoặc đối tượng, là vô dụng mà không có đồng bằng. Biết làm thế nào các con số điểm chảy hoạt động là chìa khóa để thực hiện công việc số.

Đối tượng có thể đang sử dụng .equals under the covers; nguyên thủy không có tùy chọn nào ngoài ==.

Chỉ vì phiên bản đối tượng không sử dụng đồng bằng không làm cho ý tưởng đó tốt hơn.

5

Toán kép đôi khi hiếm khi đưa ra chính xác kết quả bằng nhau. Ví dụ: 0.1 * 0.1 != 0.01. Bạn thường cần ít nhất một số đồng bằng so sánh kết quả chính xác kép.

Mặt khác, nếu bạn so sánh được đóng hộp Double s, nó giả định bạn muốn có sự bình đẳng chính xác. Java không có giá trị delta mặc định được tính đến, nhưng Double.equals có hành vi hơi khác so với ==: cụ thể là its handling of NaNs.

Điều này có ý nghĩa trong thử nghiệm, bởi vì Double.NaN != Double.NaN, nhưng trong thử nghiệm, nếu bạn mong đợi một số NaNNaN đã được trả lại, đó là câu trả lời đúng.

0

Better như thế này:

assertEquals(23.0, 250.0, 0.0) 

0,0 - đó là đồng bằng. Đọc lý do tại sao các phương pháp của bạn không được chấp nhận.