2016-08-15 20 views
11

Tôi có phương thức Java trả về Optional. Tôi muốn viết một bài kiểm tra đơn vị dễ đọc cho nó mà khẳng định rằngXác nhận rằng Tùy chọn có giá trị nhất định

  1. các tùy chọn quay trở lại có một giá trị (ví dụ, các tùy chọn là không có sản phẩm nào) và

  2. sự giá trị trả lại bằng với giá trị mong đợi.

Hãy nói rằng phương pháp thử nghiệm của tôi là

Optional<String> testedMethod(){ 
    return Optional.of("actual value"); 
} 
+2

Tôi chỉ đơn giản sử dụng 'assertEquals (" giá trị thực tế ", testingMethod(). Get());' Nó sẽ thất bại với ngoại lệ nếu tùy chọn trống, đủ để thử nghiệm đơn vị của bạn thất bại, vì vậy bạn thực sự không cần gì hơn. –

Trả lời

12

Bạn cũng có thể sử dụng AssertJ cho khẳng định thông thạo

@Test 
public void testThatOptionalIsNotEmpty() { 
    assertThat(testedMethod()).isNotEmpty(); 
} 

@Test 
public void testThatOptionalHasValue() { 
    assertThat(testedMethod()).hasValue("hello"); 
} 
1

tôi sử dụng Hamcrest Optional cho rằng:

import static com.github.npathai.hamcrestopt.OptionalMatchers.hasValue; 
import org.junit.Test; 

public class MyUnitTests { 

    @Test 
    public void testThatOptionalHasValue(){ 
    String expectedValue = "actual value"; 
    assertThat(testedMethod(), hasValue(expectedValue)); 
    } 
} 

Bạn có thể thêm hamcrest tùy chọn để phụ thuộc của bạn bằng cách bao gồm nó trong build.gradle của bạn:

dependencies { 
    testCompile 'junit:junit:4.12' 
    testCompile 'com.github.npathai:hamcrest-optional:1.0' 
} 
0

Tại sao bạn không sử dụng isPresent()get()?

+0

Đó là hai xác nhận và kết quả trong một bài kiểm tra đơn vị khá tiết. Tôi đang tìm kiếm một cái gì đó terser. –

1

Phương pháp dưới đây sử dụng thực tế là bạn có thể chỉ định một sự trở lại mặc định cho một tùy chọn. Vì vậy, phương pháp thử nghiệm của bạn có thể là một cái gì đó như thế này:

@test 
public void testThatOptionalHasValue() { 
    String expectedValue = "actual value"; 
    String actualValue = Optional.ofNullable(testedMethod()).orElse("not " + expectedValue); 
    assertEquals("The values are not the same", expectedValue, actualValue); 
} 

Người guarentees này nếu phương thức của bạn trả về null, thì kết quả không thể giống như giá trị kỳ vọng.

12

Có một số cách khác nhau để thực hiện việc này, tùy thuộc vào sở thích của bạn để làm rõ kết quả kiểm tra so với tính đồng nhất của văn bản kiểm tra. Đối với câu trả lời này tôi sẽ dính vào "chứng khoán" Java 8 và JUnit 4 không có phụ thuộc bổ sung.

Một cách, như đề xuất trong một comment by Ole V.V., chỉ đơn giản là để viết

assertEquals("correct", opt.get()); 

này chủ yếu là các công trình nhưng nếu bắt buộc là trống rỗng, sau đó get() sẽ ném NoSuchElementException. Điều này sẽ khiến JUnit báo hiệu lỗi thay vì thất bại, điều này có thể không phải là điều bạn muốn. Nó cũng không phải là rất rõ ràng những gì đang xảy ra trừ khi bạn đã biết rằng get() ném NSEE trong trường hợp này.

Một cách khác là

assertTrue(opt.isPresent() && "correct".equals(opt.get())); 

này cũng chủ yếu là các công trình nhưng nó không báo cáo giá trị thực tế nếu có sự không phù hợp, mà có thể làm cho gỡ lỗi bất tiện.

lựa chọn khác là

assertEquals("correct", opt.orElseThrow(AssertionFailedError::new)); 

này mang đến cho những thất bại ngay và báo cáo giá trị thực tế khi có sự không phù hợp, nhưng nó không phải là rất rõ ràng về việc tại sao AssertionFailedError được ném. Bạn có thể phải nhìn chằm chằm vào nó một lúc cho đến khi bạn nhận ra rằng AFE bị ném khi tùy chọn trống.

Tuy nhiên thay thế khác là

assertEquals("correct", opt.orElseThrow(() -> new AssertionFailedError("empty"))); 

nhưng điều này đang bắt đầu để có được tiết.

Bạn có thể chia thành hai khẳng định,

assertTrue(opt.isPresent()); 
assertEquals("correct", opt.get()); 

nhưng bạn trước đó đã phản đối this suggestion vì tính cách rườm rà. Điều này không thực sự khủng khiếp trong quan điểm của tôi, nhưng nó có một số chi phí nhận thức vì có hai xác nhận riêng biệt, và nó dựa vào lần thứ hai chỉ được kiểm tra nếu thành công đầu tiên. Đây không phải là không chính xác nhưng nó là một chút tinh tế.

Cuối cùng, nếu bạn sẵn sàng để tạo ra một chút cơ sở hạ tầng của riêng bạn, bạn có thể tạo một lớp con phù hợp tên của AssertionFailedError và sử dụng nó như thế này:

assertEquals("correct", opt.orElseThrow(UnexpectedEmptyOptional::new)); 

CẬP NHẬT Trong ý kiến, Ole VV đã đề xuất

assertEquals(Optional.of("correct"), opt); 

Điều này hoạt động khá tốt và thực tế điều này có thể là tốt nhất.

+0

Nếu bạn chấp nhận 'null' như một biểu diễn thông thường khác về sự vắng mặt của một giá trị, đó cũng là' assertEquals ("correct", opt.orElse (null)); Nó không phải là sở thích cá nhân của tôi, nhưng nó phải là của bạn, hãy tiếp tục. –

+10

Suy nghĩ lại, có 'assertEquals (Option‌ al.of (" corre‌ ct "), opt);' quá. Thật đáng sợ, và trong khi phải mất một thời gian để nghĩ đến việc viết nó, có thể đọc được, phải không? Tôi cũng hy vọng nó sẽ cung cấp thông điệp rõ ràng, đẹp mắt về lỗi, cả trong trường hợp 'opt' giữ giá trị sai và khi nó trống. –

+0

@ OleV.V. Đề xuất tốt! –

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