2016-02-26 13 views
5

Tôi có cấu trúc đối tượng khá phức tạp (với nhiều trường nguyên thủy và tham chiếu đối tượng) và muốn kiểm tra tất cả các trường ngoại trừ -a vài trường. Như một ví dụ;Hamcrest - Cách thanh lịch để kiểm tra đối tượng phức tạp với samepropertyvaluesas

ComplexObject actual = generateMagically("someInput"); 
ComplexObject expected = ActualFunction.instance.workMagically(actual); 

// we want to be sure that workMagically() would create a new ComplexObject 
// with some fields are different than "actual" object. 

// assertThat(actual, samePropertyValuesAs(expected)); would check all fields. 
// what I want is actually; - notice that "fieldName1" and "fieldName2" are 
// primitives belong to ComplexObject 
assertThat(actual, samePropertyValuesExceptAs(expected, "fieldName1", "fieldName2")) 

Vì tôi không muốn kiểm tra tất cả các trường theo cách thủ công, tôi tin rằng phải có cách viết bài kiểm tra đó một cách trang nhã. Ý tưởng nào?

Chúc mừng.

+0

Vì vậy, bạn có hai * túi đối tượng * và muốn thực hiện so sánh sâu? – Raffaele

+0

Không chắc chắn để gọi chúng đối tượng túi, có nhiều lĩnh vực nguyên thủy và tài liệu tham khảo đối tượng khác. Các trường tôi muốn bỏ qua là các trường nguyên thủy thuộc về ComplexObject. Chúng ta có thể nói đó sẽ là một sự so sánh sâu sắc. – tugcem

+0

Bạn có muốn thực hiện Trình phù hợp cho 'samePropertyValuesExceptAs' làm câu trả lời cho câu hỏi này không? Nếu vậy thì bạn chỉ có thể tạo một bản sao của 'org.hamcrest.beans.SamePropertyValuesAs ' và thêm vào nó một phương thức khởi tạo/phương thức tĩnh khác để loại bỏ các thuộc tính bị loại trừ khỏi việc kiểm tra. – SpaceTrucker

Trả lời

0

Nói chung, tôi thấy hai giải pháp nếu bạn tự sửa đổi ComplexObject.

Bạn có thể giới thiệu giao diện đại diện cho các thuộc tính của ComplexObject đang được thay đổi bởi ActualFunction. Sau đó, bạn có thể kiểm tra rằng tất cả các thuộc tính của giao diện mới đó đã thay đổi. Điều này sẽ yêu cầu rằng ComplexObject thực hiện giao diện mới.

Một cách tiếp cận khác là thay thế các thuộc tính của ComplextObject được thay đổi bởi ActualFunction bằng thuộc tính mới của loại mới chứa tất cả các thuộc tính đó. Một thiết kế tốt hơn sau đó sẽ cho phép ActualFunction trả về một thể hiện của loại mới.

+0

Cảm ơn SpaceTrucker. Tôi nghĩ rằng việc triển khai thực hiện một giao diện trong đối tượng miền chỉ nhằm mục đích thử nghiệm không phải là một thực hành tốt nhất (2) Đối với một cách tiếp cận khác, bạn thực sự đề nghị thêm một thuộc tính mới (tôi giả định một đối tượng mới).Một lần nữa thay đổi đối tượng chỉ để thử nghiệm, tôi đoán không. – tugcem

+0

@tugcem này không chỉ là về thử nghiệm, mà là về việc làm cho hiệu ứng của 'ActualFunction' hiển thị rõ hơn và hàm nó thể hiện rõ ràng hơn. Ví dụ, nếu việc thực hiện 'ActualFunction' sẽ thay đổi cũng thay đổi một thuộc tính khác so với hiệu ứng sẽ được hiển thị ngay lập tức nếu sử dụng phương pháp thứ hai của tôi vì kiểu mới sẽ nhận được thuộc tính mới đó. – SpaceTrucker

+0

Tôi thực sự không cần đặt thêm biểu thức hoặc khả năng hiển thị vào hàm workMagically() về việc thay đổi các thuộc tính. Infact, chúng tôi không muốn nói bất cứ điều gì rõ ràng về các lĩnh vực cập nhật và mong đợi người dùng của lớp này phải nhận thức được điều này. – tugcem

0

Lần cuối cùng tôi có yêu cầu tương tự, tôi đã đi đến kết luận rằng viết thủ công cả mã và kiểm tra để khẳng định rằng một số giá trị được cập nhật vốn đã dễ bị lỗi và dễ xảy ra lỗi.

Tôi đã ngoại vi hóa các trường trong đối tượng túi và tạo tệp nguồn Java cho cả lớp túi và trình sao chép tại thời gian biên dịch. Bằng cách này, bạn có thể kiểm tra mã thực tế (trình tạo) và có định nghĩa thực sự của miền ở chính xác một nơi, vì vậy mã sao chép không thể lỗi thời.

Ngôn ngữ để mô tả tài sản có thể được bất cứ điều gì bạn cảm thấy thoải mái với, từ JSON-schema to XML Java bản thân (Java ví dụ sau - chú thích tùy chỉnh sẽ được tiêu thụ từ các máy phát điện)

public class MyBag { 
    @Prop public int oh; 
    @Prop public String yeah; 
} 
7

Bạn cần xem xét shazamcrest, một tiện ích mở rộng tuyệt vời Hamcrest cung cấp những gì bạn cần.

assertThat(expected, sameBeanAs(expectedPerson).ignoring("fieldName1").ignoring("fieldName2")); 

Xem https://github.com/shazam/shazamcrest#ignoring-fields

+1

Nếu có ai thắc mắc '' 'sameBeanAs''' ở đâu, nó nằm trong lớp học ' '' com.shazam.shazamcrest.matcher.Matchers'''. –

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