Reputation: 51
Hey I'm trying to use both @MethodSource and @EnumSource in the same @ParameterizedTest i tried doing the following
@ParameterizedTest
@MethodSource("methodTest")
@EnumSource(value = CountryDetails::class, mode = EnumSource.Mode.INCLUDE, names = ["A", "B", "C", "D"])
fun `test name`(
country: CountryDetails,
amount: BigDecimal,
rich: Boolean,
hight: Int,
) {
// here goes my test
}
@JvmStatic
fun methodTest(): Stream<Arguments> = Stream.of(
Arguments.of(BigDecimal(800), false, 50),
Arguments.of(BigDecimal(900), true, 50),
)
However I'm getting this error
Error converting parameter at index 0: No implicit conversion to convert object of type java.math.BigDecimal to type com.test.country.CountryDetails org.junit.jupiter.api.extension.ParameterResolutionException: Error converting parameter at index 0: No implicit conversion to convert object of type java.math.BigDecimal
Upvotes: 3
Views: 3246
Reputation: 27226
The provided answers should give you enough info, just so you know, You don't need a data class either if you don't want...
If your test is simple you can provide more values using Pairs or Triples in Kotlin as well so.
Imagine you want to test a phone number validator and need to supply country code, phone number, and the expected result:
Stream.of(
//Country Code, Phone number, expected value
Arguments.of(Pair("", ""), ""),
Arguments.of(Pair("", "12345"), "12345"),
Arguments.of(Pair("+31", "12345"), "+3112345")
You get the idea.
Your test would look like:
@ParameterizedTest
@MethodSource("methodTest")
fun testXXX(input: Pair<String, String>, expected: String) {
val formatted = subject.format(input.first, input.second)
assertEquals(expected, formatted)
}
Keep it in mind as it may make your test simpler.
Upvotes: 0
Reputation: 5209
This will not work, as the method source function provides 3 parameters and must be used by a function with 3 parameters, and the enum source provides 1 parameter and should be used by a function that takes 1 parameter.
The two annotations are completely independent of each other.
If you want some sort of cartesian product of the enums and the parameters you'll have to do it in a loop in the method source:
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import java.math.BigDecimal
import java.util.stream.Stream
enum class CountryDetails {
A, B, C, D
}
data class MethodArgs(val country: CountryDetails, val amount: BigDecimal, val rich: Boolean, val height: Int)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class Test {
@ParameterizedTest
@MethodSource("methodTest")
fun `test name`(
methodArgs: MethodArgs
) {
// here goes my test
}
private fun methodTest(): Stream<MethodArgs> =
listOf(CountryDetails.A, CountryDetails.B, CountryDetails.C, CountryDetails.D).map {
listOf(MethodArgs(it, BigDecimal(800), false, 50), MethodArgs(it, BigDecimal(900), true, 50))
}.flatten().stream()
}
A couple of points on the code - the test instance annotation means you don't have to write static methods.
Use of a data class makes things a lot easier when dealing with lots of parameters.
Upvotes: 1