Bạn có thể thêm thông báo tùy chỉnh vào AssertJ khẳng địnhThat không?


90

Chúng tôi có một bộ thử nghiệm chủ yếu sử dụng các xác nhận JUnit với các trình khớp Hamcrest. Một trong nhóm của chúng tôi đã bắt đầu thử nghiệm với AssertJ và gây ấn tượng với mọi người về cú pháp, tính linh hoạt và khả năng khai báo của nó. Có một tính năng mà JUnit cung cấp mà tôi không thể tìm thấy tính năng tương đương trong AssertJ: thêm thông báo lỗi xác nhận tùy chỉnh.

Chúng tôi thường so sánh các đối tượng không được tạo ra để con người có thể đọc được và sẽ có các Id hoặc UUID trông có vẻ ngẫu nhiên và không thể biết chúng là gì bằng dữ liệu chúng chứa. Đây là một tình huống không thể tránh khỏi đối với cơ sở mã của chúng tôi, đáng buồn thay, một phần của mục đích mà nó thực hiện là ánh xạ dữ liệu giữa các dịch vụ khác mà không nhất thiết phải hiểu nó là gì.

Trong JUnit, assertThatphương thức cung cấp một phiên bản có String reasontham số trước tham số Matcher<T>. Điều này làm cho việc thêm một chuỗi gỡ lỗi ngắn làm sáng tỏ vấn đề, giống như ý nghĩa của phép so sánh đối với con người.

Mặt khác, AssertJ cung cấp hàng nghìn phương thức tổng quát hóastatic assertThat khác nhau trả về một số dạng Assert giao diện hoặc một trong nhiều lớp triển khai của nó. Giao diện này không cung cấp một cách tiêu chuẩn để thiết lập một thông báo tùy chỉnh được đưa vào các lỗi.

Có cách nào để có được chức năng này từ API AssertJ hoặc một trong các tiện ích mở rộng của nó mà không cần phải tạo lớp xác nhận tùy chỉnh cho mọi loại xác nhận mà chúng tôi muốn thêm thông báo vào không?

Câu trả lời:


137

Và theo phong cách cổ điển, tôi đã tìm thấy những gì tôi đang tìm kiếm ngay sau khi đăng câu hỏi. Hy vọng rằng điều này sẽ giúp người tiếp theo tìm thấy dễ dàng hơn mà không cần biết nó được gọi là gì. Magic method được đặt tên ngắn gọn as, là một phần của một giao diện khác AbstractAssertthực hiện: Có thể mô tả , không phải giao diện Assert cơ sở.

public S as(String description, Object... args)

Đặt mô tả về String.format(String, Object...)cú pháp hỗ trợ đối tượng này .
Thí dụ :

try {
  // set a bad age to Mr Frodo which is really 33 years old.
  frodo.setAge(50);
  // you can specify a test description with as() method or describedAs(), it supports String format args
  assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
} catch (AssertionError e) {
  assertThat(e).hasMessage("[check Frodo's age] expected:<[33]> but was:<[50]>");
}

Trong đó chuỗi được trích dẫn trong khối bắt hasMessagelà những gì xuất hiện trong nhật ký đầu ra kiểm tra đơn vị của bạn nếu xác nhận không thành công.


Tôi tìm thấy điều này bằng cách nhận thấy người failWithMessagetrợ giúp trong trang xác nhận tùy chỉnh được liên kết trong câu hỏi. Các javadoc cho phương pháp đó chỉ ra rằng nó được bảo vệ, vì vậy nó không thể được sử dụng bởi những người gọi để thiết lập một thông báo tùy chỉnh. Tuy nhiên, nó đề cập đến người astrợ giúp:

Hơn nữa, phương pháp này tôn vinh bất kỳ bộ mô tả nào có as(String, Object...)hoặc thông báo lỗi ghi đè được xác định bởi người dùng với overridingErrorMessage(String, Object...).

... và trình trợ giúp overridingErrorMessage , thay thế hoàn toàn expected: ... but was:...thông báo AssertJ tiêu chuẩn bằng chuỗi mới được cung cấp.

Trang chủ AssertJ không đề cập đến công cụ trợ giúp nào cho đến khi trang đánh dấu các tính năng, hiển thị các ví dụ về công cụ astrợ giúp trong phần Xác định mềm , nhưng không trực tiếp mô tả chức năng của nó.


23

Để thêm một tùy chọn khác vào câu trả lời của Patrick M:

Thay vì sử dụng Descriptable.as, bạn cũng có thể sử dụng AbstractAssert.withFailMessage():

try {
  // set a bad age to Mr Frodo which is really 33 years old.
  frodo.setAge(50);
  // you can specify a test description via withFailMessage(), supports String format args
  assertThat(frodo.getAge()).
    withFailMessage("Frodo's age is wrong: %s years, difference %s years",
      frodo.getAge(), frodo.getAge()-33).
    isEqualTo(33);
} catch (AssertionError e) {
  assertThat(e).hasMessage("Frodo's age is wrong: 50 years, difference 17 years");
}

Sự khác biệt khi sử dụng Descriptable.aslà nó cho phép bạn kiểm soát hoàn toàn thông báo tùy chỉnh - không có "mong đợi" và "nhưng là".

Điều này rất hữu ích khi các giá trị thực tế đang được kiểm tra không hữu ích cho việc trình bày - phương pháp này cho phép bạn hiển thị các giá trị khác, có thể được tính toán thay thế hoặc không có giá trị nào.


Lưu ý rằng, giống như Descriptable.as, bạn phải gọi withFailMessage() trước bất kỳ xác nhận thực tế nào - nếu không, nó sẽ không hoạt động, vì xác nhận sẽ kích hoạt trước. Điều này được ghi nhận trong Javadoc.


3
"bạn phải gọi bằngFailMessage () trước khi có bất kỳ xác nhận thực tế nào" cảm ơn, điều này đã vấp phải tôi. Thứ tự gọi withFailMessagevật chất; Tôi thích AssertJ, nhưng điều này thật tệ.
Abhijit Sarkar,


0

Sử dụng as()phương thức sẵn có trong AssertJ. Ví dụ:

 assertThat(myTest).as("The test microservice is not active").isEqualTo("active");
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.