2014-12-31 18 views
5

Tôi đang cố gắng thay thế JMock bằng Mockito (1.10.17). Tôi đã thực hiện một số xét nghiệm đơn vị thành công, nhưng bây giờ tôi muốn sử dụng tính năng timeoutjava.lang.VerifyError với Mockito 1.10.17

verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class)); 

và tôi nhận được ngoại lệ này:

java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function 
    at org.mockito.verification.Timeout.<init>(Timeout.java:32) 
    at org.mockito.verification.Timeout.<init>(Timeout.java:25) 
    at org.mockito.Mockito.timeout(Mockito.java:2164) 

Vấn đề này xảy ra trong IntelliJ và với Maven. Chỉ có 1 phiên bản của Mockito trên classpath. Ngoài ra còn có JMock 2.5.1 trên classpath mà tôi không thể loại bỏ vì 99% các bài kiểm tra đơn vị của tôi vẫn sử dụng JMock tại thời điểm này. Tôi không biết liệu nó có liên quan gì đến nó không.

CẬP NHẬT: Tôi đã thử với JMock 2.6.0 và Hamcrest 1.3 nhưng kết quả là như nhau.

UPDATE 2:

này hoạt động:

Thread.sleep(5000); 
verify(m_publisher).notifySubscribers(any(BecameMasterMessage.class)); 

Và đây không:

verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class)); 

UPDATE 3: Tôi đã thực hiện một dự án thử nghiệm nhỏ mà có vấn đề chính xác cùng : Xem https://github.com/wimdeblauwe/mockito-verify-problem và chạy nó từ IntelliJ hoặc với Maven.

+0

Đây là câu hỏi "tắt đi và bật lại" ngớ ngẩn, nhưng nó lại hỏi: Bạn đã dọn dẹp các tạo phẩm biên dịch chưa? Thậm chí nếu chỉ có một phiên bản của Mockito trên classpath, VerificationOverTimeImpl mới được đổi tên từ VerificationWithTimeoutImpl 1.9.5 và nếu bạn đã từng sử dụng 1.9.5 hoặc sớm hơn một số tệp lớp học kéo dài có thể đang ném mọi thứ. –

+0

@JeffBowman Tôi đã làm một 'mvn clean install' để chắc chắn rằng đó không phải là vấn đề. Bây giờ tôi đã chỉnh sửa câu hỏi với một liên kết đến một dự án mẫu cho thấy vấn đề. –

Trả lời

5

Vấn đề ở đây là một chòm sao không may giữa TestNG, JUnit và Mockto. Để khắc phục vấn đề của bạn, bạn chỉ cần thêm một phụ thuộc vào JUnit 4.0 hoặc mới hơn (phiên bản mới nhất hiện đang 4.12):

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.12</version> 
</dependency> 

Dưới đây là chi tiết:

TestNG, mà rõ ràng là thử nghiệm của bạn khuôn khổ, tuyên bố một sự phụ thuộc vào phiên bản JUnit khá cũ 3.8.1. Mockito không khai báo sự phụ thuộc vào JUnit nhưng nó sử dụng một số lớp JUnit được giới thiệu trong JUnit 4.0 (!).

Edit:

Phương pháp này Mockito#timeout() trong ví dụ của bạn tạo ra một trường hợp Timeout do đó tạo ra một thể hiện của VerificationOverTimeImpl. Phương pháp VerificationOverTimeImpl#verify() xử lý lỗi loại ArgumentsAreDifferent là lớp con của org.junit.ComparisonFailure.

Từ phiên bản JUnit 3.8.1 đến 4.x phân cấp lớp của ComparisonFailure thay đổi thành có AssertionError thay vì Error làm lớp cơ sở. VerifiyError được gây ra bởi vì VerificationOverTimeImpl#handleVerifyException() yêu cầu AssertionError nhưng sẽ được gọi với số Error khi sử dụng JUnit 3.8.1.

+0

Xin cảm ơn, sẽ sửa lỗi đó ngay bây giờ. Nó sẽ không tốt hơn cho mockito để tuyên bố một phụ thuộc vào JUnit? Sau đó, Maven sẽ chọn vấn đề phiên bản JUnit tốt. –

+0

'org.mockito.exceptions.verification.junit.ArgumentsAreDifferent' mở rộng' junit.framework.ComparisonFailure', 'VerifyError' là một vấn đề liên kết. JVM nghĩ rằng 'junit.framework.ComparisonFailure' trong JUnit 3.x và JUnit 4.x là đủ khác nhau để thất bại khi liên kết' org.mockito.exceptions.verification.junit.ArgumentsAreDifferent'. Dù sao trên mặt trước mockito vấn đề là phần này của API không nên dựa vào JUnit. – Brice

+0

Điều này cũng tiết lộ rằng Mockito không còn tương thích với JUnit 3.x – Brice

0

CHỈNH SỬA: Có vẻ như câu trả lời ban đầu được trả lời trước. Tuy nhiên, chẩn đoán của anh gần như chính xác, org.mockito.exceptions.verification.junit.ArgumentsAreDifferent mở rộng junit.framework.ComparisonFailure, có trong JUnit 3.x và nó phụ thuộc vào TestNG 5.x. Bản thân số VerifyError có thể có gì đó cần làm khi JVM thực hiện liên kết vì có thay đổi trong chính loại ComparisonFailure giữa JUnit 3.x và JUnit 4.x.

Dù sao vấn đề trong Mockito là nó sử dụng một lớp JUnit nơi nó không nên.Và rằng Mockito không hỗ trợ nữa JUnit 3.x.

tl; tr

Chúng tôi có một vấn đề trong các mã trong nội bộ chế độ xác minh bạn đang sử dụng sử dụng một lớp JUnit, đó không phải là trên classpath. Thêm JUnit trong sự phụ thuộc của POM của bạn sẽ sửa chữa mọi thứ.

Cảm ơn bạn đã báo cáo. Tôi đã tạo ra một vấn đề về GitHub (#152)

dài câu chuyện

Đối với một số lý do TestNG 5.xxx làm cho JVM thất bại với một VerifyError, trên một phương pháp mà thậm chí không được gọi vào thời điểm đó.

java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: 
    (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function 

Nhưng chuyển sang phiên bản mới nhất của TestNG, 6.8.something làm cho JVM thất bại với một nguyên nhân dễ hiểu: NoClassDefFoundError

java.lang.NoClassDefFoundError: junit/framework/ComparisonFailure 

nào trỏ tới vấn đề thực sự ở đây, bây giờ chỉ có tìm mà lớp phụ thuộc vào JUnit. Lớp này là ArgumentsAreDifferent mở rộng junit.framework.ComparisonFailure, ngoại lệ này xuất hiện trong khối try/catch trong số VerificationOverTimeImpl cần thiết để xác minh thời gian chờ.

Sự cố này đã có thể xảy ra kể từ 1.10.x khi khắc phục một số vấn đề thời gian chờ.

Lưu ý tôi cũng đã sao chép câu trả lời này trên số mailing list.

+0

Bạn đúng, 'ArgumentsAreDifferent' kéo dài từ' junit.framework.ComparisonFailure'. Vì vậy, câu trả lời của tôi là khá sai tại thời điểm đó. Sau khi điều tra vấn đề thêm một chút, tôi nghĩ rằng vấn đề là phân cấp lớp của 'CompareFailure'. Nó là một lớp con của 'AssertionFailedError' là một lớp con của' Lỗi' trong JUnit 3.8.1 ** nhưng ** một lớp con của 'AssertionError' trong JUnit 4.x. Khi sửa đổi phiên bản 3.8.1 của 'AssertionFailedError' thành một lớp con của' AssertionError', mọi thứ hoạt động tốt. –

+0

@StefanFerstl Tốt bắt! Có khả năng nhất là JVM thấy sự thay đổi phân cấp này là một lỗi khi nó thực hiện liên kết. – Brice

Các vấn đề liên quan