我有一個返回Optional的Java方法。 我想編寫一個易於閱讀的單元測試它斷言斷言可選具有一定的值
返回可選有一個值(即擇不爲空),並且
的返回值等於預期值。
比方說,我的測試方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
我有一個返回Optional的Java方法。 我想編寫一個易於閱讀的單元測試它斷言斷言可選具有一定的值
返回可選有一個值(即擇不爲空),並且
的返回值等於預期值。
比方說,我的測試方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
您還可以使用AssertJ爲流暢的斷言
@Test
public void testThatOptionalIsNotEmpty() {
assertThat(testedMethod()).isNotEmpty();
}
@Test
public void testThatOptionalHasValue() {
assertThat(testedMethod()).hasValue("hello");
}
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));
}
}
您可以通過它在你的build.gradle
添加Hamcrest可選到你的依賴:
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'com.github.npathai:hamcrest-optional:1.0'
}
爲什麼不使用isPresent()
和get()
?
這是兩個斷言,並導致一個非常詳細的單元測試。我在找東西。 –
下面的方法使用的事實,你可以指定一個可選的一個默認的回報。所以你的測試方法可能是這樣的:
@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);
}
這guarentees,如果你的方法返回null,則結果不能是相同的預期值。
有幾種不同的方法可以做到這一點,這取決於您的口味,以便測試結果的清晰度和測試寫作的簡潔性。對於這個答案,我將堅持「股票」Java 8和JUnit 4沒有額外的依賴。
的一種方式,如在comment by Ole V.V.建議,僅僅是寫
assertEquals("correct", opt.get());
這主要工作,但如果可選爲空,則get()
將拋出NoSuchElementException
。這反過來導致JUnit發出錯誤信號而不是錯誤信號,這可能不是您想要的。這也不是很清楚,除非你已經知道get()
在這種情況下拋出NSEE。
另一種方法是
assertTrue(opt.isPresent() && "correct".equals(opt.get()));
這也主要是作品,但如果有一個不匹配,這可能使調試不方便它不報告的實際值。
另一種方法是
assertEquals("correct", opt.orElseThrow(AssertionFailedError::new));
這給正確的失敗和報告的實際價值時,有一個不匹配,但它不是關於爲什麼AssertionFailedError
被拋出非常明確的。您可能不得不盯住它,直到您意識到AFE在Optional爲空時被拋出。
還有另一種選擇是
assertEquals("correct", opt.orElseThrow(() -> new AssertionFailedError("empty")));
但這開始變得冗長。
你可以分裂成兩個斷言此,
assertTrue(opt.isPresent());
assertEquals("correct", opt.get());
,但你此前曾反對this suggestion因爲冗長的。這在我看來並不是非常詳細,但是它確實存在一些認知開銷,因爲有兩個單獨的斷言,並且只有在第一次成功時才依靠第二次檢查。這不是不正確的,但它有點微妙。
最後,如果你願意創建一個有點自己的基礎設施,您可以創建的AssertionFailedError
適當命名的子類,並使用它像這樣:
assertEquals("correct", opt.orElseThrow(UnexpectedEmptyOptional::new));
UPDATE在評論,奧VV建議
assertEquals(Optional.of("correct"), opt);
這工作得很好,實際上這可能是最好的。
如果您接受'null'作爲缺少值的另一個常規表示形式,則還有'assertEquals(「correct」,opt.orElse(null));'。這不是我個人的偏好,但它應該是你的,繼續。 –
再想一想,有'assertEquals(Option al.of(「corre ct」),opt);''也是。這很簡單,雖然我花了一段時間想寫它,但可以閱讀,不是嗎?我也希望它在失敗的時候給出好的,明確的信息,在'opt'存在錯誤值和空白的情況下。 –
@ OleV.V。好建議! –
我只是簡單地使用'assertEquals(「actual value」,testedMethod()。get());'如果可選項爲空,它將會失敗,這足以讓你的單元測試失敗,所以你真的不需要更多。 –