JUnit單元測試有時在一個@Test
測試方法中會需要用多個Assertions來驗證,例如回傳結果物件的所有屬性是否皆正確。而直接執行多個Assertions及使用JUnit 5才有的Assertions.assertAll()
區別如下。
使用多個Assertions若前面的assert結果錯誤或發生例外,則測試停止,後面的Assertions不會繼續執行。
而使用Assertions.assertAll()
群組多個Assertions時,若前面的assert結果錯誤或發生例外,測試不會停止,後面的Assertions仍繼續執行,任一錯務結果會印在MultipleFailuresError訊息中。
例如下面的Main.getEmployeeOfTheYear()
是要被測試的程式。
Main
public class Main {
public Employee getEmployeeOfTheYear() {
return new Employee(1, "John", 28);
}
}
在MainTests
測試類分別在test_multi_assertions()
用多個Assertions及在test_assertAll()
assertAll()
進行測試。
MainTests
public class MainTests {
private final Main main = new Main();
@Test
public void test_multi_assertions() {
Employee employee = main.getEmployeeOfTheYear();
Assertions.assertEquals(3, employee.getId());
Assertions.assertEquals("Mary", employee.getName());
Assertions.assertEquals(33, employee.getAge());
}
@Test
public void test_assertAll() {
Employee employee = main.getEmployeeOfTheYear();
Assertions.assertAll(
() -> Assertions.assertEquals(3, employee.getId()),
() -> Assertions.assertEquals("Mary", employee.getName()),
() -> Assertions.assertEquals(33, employee.getAge())
);
}
}
test_multi_assertions()
測試結果印出以下。
MainTests.test_multi_assertions()
org.opentest4j.AssertionFailedError:
Expected :3
Actual :1
<Click to see difference>
...
at com.abc.demo.MainTests.test_multi_assertions(MainTests.java:15)...
at java.util.ArrayList.forEach(ArrayList.java:1257)...
at java.util.ArrayList.forEach(ArrayList.java:1257)...
test_assertAll()
測試結果印出以下。
MainTests.test_assertAll()
expected: <3> but was: <1>
Comparison Failure:
Expected :3
Actual :1
<Click to see difference>
expected: <Mary> but was: <John>
Comparison Failure:
Expected :Mary
Actual :John
<Click to see difference>
expected: <33> but was: <28>
Comparison Failure:
Expected :33
Actual :28
<Click to see difference>
org.opentest4j.MultipleFailuresError: Multiple Failures (3 failures)
org.opentest4j.AssertionFailedError: expected: <3> but was: <1>
org.opentest4j.AssertionFailedError: expected: <Mary> but was: <John>
org.opentest4j.AssertionFailedError: expected: <33> but was: <28>
...
at com.abc.demo.MainTests.test_assertAll(MainTests.java:25)...
at java.util.ArrayList.forEach(ArrayList.java:1257)...
at java.util.ArrayList.forEach(ArrayList.java:1257)...
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Suppressed: org.opentest4j.AssertionFailedError: expected: <3> but was: <1>
at com.abc.demo.MainTests.lambda$test_assertAll$0(MainTests.java:26)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.junit.jupiter.api.AssertAll.assertAll(AssertAll.java:77)
... 69 more
Suppressed: org.opentest4j.AssertionFailedError: expected: <Mary> but was: <John>
at com.abc.demo.MainTests.lambda$test_assertAll$1(MainTests.java:27)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.junit.jupiter.api.AssertAll.assertAll(AssertAll.java:77)
... 69 more
Suppressed: org.opentest4j.AssertionFailedError: expected: <33> but was: <28>
at com.abc.demo.MainTests.lambda$test_assertAll$2(MainTests.java:28)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.junit.jupiter.api.AssertAll.assertAll(AssertAll.java:77)
... 69 more
那Assertions.assertAll()
和拆成多個test方法又有什麼差別呢?Assertions.assertAll()
是方便用來測試一個方法同個輸入的輸出結果內含多個值的情況(不過比較物件或許用equals()
就好?)。如果輸入不同那應該還是要拆成多個測試方法。
沒有留言:
張貼留言