Java JUnit: Phương thức X không rõ ràng đối với kiểu Y


98

Tôi đã có một số bài kiểm tra hoạt động tốt. Sau đó, tôi đã chuyển nó sang một gói khác và hiện đang gặp lỗi. Đây là mã:

import static org.junit.Assert.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jgrapht.Graphs;
import org.jgrapht.WeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;
import org.junit.*; 

@Test
    public void testEccentricity() {
        WeightedGraph<String, DefaultWeightedEdge> g = generateSimpleCaseGraph();
        Map<String, Double> eccen = JGraphtUtilities.eccentricities(g);

        assertEquals(70, eccen.get("alpha"));
        assertEquals(80, eccen.get("l"));
        assertEquals(130, eccen.get("l-0"));
        assertEquals(100, eccen.get("l-1"));
        assertEquals(90, eccen.get("r"));
        assertEquals(120, eccen.get("r-0"));
        assertEquals(130, eccen.get("r-1"));
    }

Thông báo lỗi là:

Phương thức khẳng địnhEquals (Đối tượng, Đối tượng) không rõ ràng đối với kiểu JGraphtUtilitiesTest

Làm thế nào tôi có thể sửa lỗi này? Tại sao sự cố này lại xảy ra khi tôi chuyển lớp sang một gói khác?


cho chúng tôi biết lớp của bạn được khai báo như thế nào. Với tôi như thể bạn đã kế thừa từ JUnit3 và sau đó cố gắng nhập tĩnh từ JUnit4.
bmargulies

vâng, thực ra, tôi đã có JUnit3 trong gói A và sử dụng JUnit4 trong gói B, nơi tôi đã viết các bài kiểm tra này ban đầu. Sau đó, tôi chuyển từ Gói B sang Gói A, và vấn đề nảy sinh. Nhưng tôi không thấy bất kỳ thứ gì trong lớp này cho biết JUnit 3. Cái đó được khai báo ở đâu?
Nick Heiner

@Rosarch Các tiện ích JGrapht này có sẵn ở bất kỳ đâu không? Tôi không thể thấy các phương pháp tạo ra sự lập dị trong JGraphT!
Nick

Câu trả lời:


205

Phương thức khẳng địnhEquals (Đối tượng, Đối tượng) không rõ ràng đối với kiểu ...

Lỗi này có nghĩa là bạn đang chuyển một doublevà và Doublevào một phương thức có hai chữ ký khác nhau: assertEquals(Object, Object)assertEquals(double, double)cả hai chữ ký này đều có thể được gọi, nhờ vào autoboxing.

Để tránh sự mơ hồ, hãy đảm bảo rằng bạn gọi assertEquals(Object, Object)(bằng cách chuyển hai lần Đôi) hoặc assertEquals(double, double)(bằng cách chuyển hai lần đôi).

Vì vậy, trong trường hợp của bạn, bạn nên sử dụng:

assertEquals(Double.valueOf(70), eccen.get("alpha"));

Hoặc là:

assertEquals(70.0d, eccen.get("alpha").doubleValue());

được, hoặc tôi có thể chuyển nó sang sử dụng JUnit 4 thay vì JUnit 3. Làm cách nào để làm điều đó?
Nick Heiner

8
Giải pháp không thực sự là chuyển từ phiên bản này sang phiên bản khác. Thay vào đó, hãy trợ giúp trình biên dịch và loại bỏ sự mơ hồ như tôi đã đề xuất.
Pascal Thivent

1
Dù sao, nó không nên là khẳng địnhEquals (70.0d, eccen.get ("alpha")); ?
mhaller

3
@mahller Không chắc bạn đang nói chuyện với ai nhưng, ngay cả khi nó đúng hơn mã của OP, vẫn không rõ ràng nếu phiên bản của JUnit có cả hai assertEquals(Object, Object)assertEquals(double, double)đó là trường hợp của JUnit 4.4, 4.5. Nhưng như tôi đã nói, thay đổi phiên bản JUnit không phải là giải pháp thực sự, chỉ là khắc phục sự cố.
Pascal Thivent

1
@Rosarch Đối với trường hợp cụ thể này, đó không phải là vấn đề trong JUnit 3.8.1, không phải là vấn đề trong JUnit 4.3, đó vấn đề trong JUnit 4.4, đó vấn đề trong JUnit 4.5 (nhưng phương pháp lấy 2 doubles không được dùng nữa), đây không phải là vấn đề trong JUnit 4.6 (phương thức đã bị xóa). Vì vậy, hãy lựa chọn của bạn, nhưng bạn nên sửa mã.
Pascal Thivent

1

Bạn có thể sử dụng phương pháp

assertEquals(double expected, double actual, double delta)

Điều này sẽ tính đến lỗi làm tròn đang cản trở thành dấu phẩy động ( ví dụ: xem bài đăng này ). Bạn có thể viết

assertEquals(70, eccen.get("alpha"), 0.0001);

Điều này có nghĩa là miễn là hai giá trị khác nhau dưới 0,0001 thì chúng được coi là bằng nhau. Điều này có hai lợi thế:

  • So sánh các giá trị dấu phẩy động vì chúng được cho là
  • Không cần ép kiểu, vì ba đối số khẳng định chỉ áp dụng cho các đối tượng gấp đôi, không áp dụng cho các Đối tượng chung chung

0

Giải pháp đơn giản nhất cho vấn đề này là chỉ ép tham số thứ hai thành một tham số nguyên thủy:

assertEquals(70, (double)eccen.get("alpha"));

Đã loại bỏ sự mơ hồ.

Điều này hợp lệ cho bất kỳ lớp con Number nào, ví dụ:

assertEquals(70, (int)new Integer(70));

Cũng sẽ giải quyết một sự mơ hồ.

Tuy nhiên, khẳng định Equals (double, double) hiện không được dùng nữa và vì những lý do chính đáng, vì vậy tôi khuyến khích bạn sử dụng phương pháp với delta như những người khác đã đề xuất.

Bởi vì lý do chính đáng, tôi muốn nói rằng, với sự biểu diễn bên trong của các số kép, hai số kép rõ ràng bằng nhau có thể khác nhau ở một phần thập phân không liên quan và sẽ không vượt qua bài kiểm tra, nhưng điều đó không có nghĩa là mã của bạn có gì sai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.