Nếu các bạn đã thực hiện unit test
với JUnit4 có một điểm yếu là không hỗ trợ parameters
cho test method
dẫn tới việc phải dupl code rất nhiều gây khó khăn cho việc review, update test case
👎. Điểm yếu này có thể khắc phục bằng TestNG. Rất may, JUnit5 ra đời với nhiều cải tiến, trong đó Parameterized Test
là cải tiến giúp ta khắc phục được điểm yếu trên ❤️.
Required Setup
Để sử dụng Parameterized Tests
ta cần dependency là junit-jupiter-params
.
Với Gradle
ta thêm:
|
|
Với Maven
ta thêm:
|
|
Argument Sources
Các tham số của Parameterized Tests
được cung cấp bởi các Argument Sources
sau:
@ValueSource
Là cách đơn giản nhất để cung cấp data test cho Parameterized Tests
. Cách này chỉ hỗ trợ các kiểu literal
sau:
- short
- byte
- int
- long
- float
- double
- char
- boolean
- java.lang.String
- java.lang.Class
Ví dụ sau sẽ test hàm String.isNullOrBlank
với 6 trường hợp được liệt kê ở @ValueSource
:
|
|
Và để test 2 trường hợp đặc biệt null
và empty
ta có thể sử dụng @NullSource
và @EmptySource
hoặc dùng @NullAndEmptySource
.
@EnumSource
Để test với data test là enum
. Mặc định data test là tất cả các giá trị thuộc enum
. Trường hợp chỉ muốn test một vài giá trị trong enum
ta có thể làm giống ví dụ.
Ví dụ kiểm tra những tháng 4, 6, 9 và 11 có 30 ngày thuộc enum
Month
:
|
|
@MethodSource
@ValueSource
và @EnumSource
chỉ có thể cung cấp các data test đơn giản. Những trường hợp phức tạp ta có thể factory method
để cung cấp data test. Một lưu ý là factory method
phải là static
.
Ví dụ này mình sẽ tối ưu so với bài Use Mock to make Unit Test easy với chỉ một test method
:
|
|
và data test sẽ được cung cấp qua:
|
|
Lưu ý: data trả về của factory method
phải là Stream
của các Arguments
. Tuy nhiên JUnit5
có hỗ trợ các kiểu khác như:
DoubleStream
LongStream
IntStream
Collection
Iterator
Iterable
Một mảng của các objects
Một mảng của các primitives
@CsvSource
Data test sẽ được cung cấp bởi comma-separated values
Ví dụ sau kiểm tra hàm String.toUpperCase
:
|
|
@CsvFileSource
Tương tự như @CsvSource
nhưng data test được load từ file.
Ví dụ sau kiểm tra hàm String.toUpperCase
:
|
|
với data test file:
str,expected
trile,TRILE
tRilE,TRILE
trILE,TRILE
@ArgumentsSource
Cũng tương tự như @MethodSource
nhưng data test được cung cấp bởi một implements class
của ArgumentsProvider
thay vì một factory method
. Cá nhân mình thấy @ArgumentsSource
không tốt bằng
Ví dụ test input argument khác null
:
|
|
data test được cung cấp bởi:
|
|
Customizing Display Names
Một điểm yếu của Parameterized Tests
đó là hiển thị kết quả test không được rõ nghĩa lắm. Ví dụ như:
|
|
sẽ trả về kết quả sau (với Gradle
test report):
Test | Method name | Duration | Result |
---|---|---|---|
[1] month=APRIL | test month have 30 day(Month)[1] | 0.033s | passed |
[2] month=JUNE | test month have 30 day(Month)[2] | 0.001s | passed |
[3] month=SEPTEMBER | test month have 30 day(Month)[3] | 0.001s | passed |
[4] month=NOVEMBER | test month have 30 day(Month)[4] | 0.001s | passed |
nhưng sẽ hơi tối nghĩa nên mình sẽ thay đổi chút như sau:
|
|
thì kết quả sẽ đẹp hơn:
Test | Method name | Duration | Result |
---|---|---|---|
#1 - [APRIL] have 30 day | test month have 30 day(Month)[1] | 0.034s | passed |
#2 - [JUNE] have 30 day | test month have 30 day(Month)[2] | 0.001s | passed |
#3 - [SEPTEMBER] have 30 day | test month have 30 day(Month)[3] | 0.001s | passed |
#4 - [NOVEMBER] have 30 day | test month have 30 day(Month)[4] | 0.001s | passed |
{index}
là số thứ tự của các data test.{arguments}
danh sách tất cả cácargument name
vàargument value
.{0}
,{1}
, … làargument value
theo thứ tự bắt đầu từ 0.