Mat*_*Pag 9 junit android unit-testing kotlin
我需要类似于 C# NUnit TestCase场景的东西,具有固定的预期结果。
我已经在 SO 上找到了这个问题,它有很好的解决方案,但它们仅适用于 Java,并且正如我遵循本教程的一些答案中所建议的那样,但简单地将其转换为 Kotlin 是行不通的。
@RunWith(value = Parameterized.class)
public class EmailIdValidatorTest {
private String emailId;
private boolean expected;
public EmailIdValidatorTest(String emailId, boolean expected) {
this.emailId = emailId;
this.expected = expected;
}
@Parameterized.Parameters(name= "{index}: isValid({0})={1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{"mary@testdomain.com", true},
{"mary.smith@testdomain.com", true},
{"mary_smith123@testdomain.com", true},
{"mary@testdomaindotcom", false},
{"mary-smith@testdomain", false},
{"testdomain.com", false}
}
);
}
@Test
public void testIsValidEmailId() throws Exception {
boolean actual= EmailIdUtility.isValid(emailId);
assertThat(actual, is(equalTo(expected)));
}
}
Run Code Online (Sandbox Code Playgroud)
那么使用 JUnit 编写 Kotlin 参数化单元测试的正确方法是什么?
Mat*_*Pag 10
按照这个惊人的教程,我们可以用 Kotlin 语言以这种方式实现它:
首先将EmailIdUtility类转换为 Kotlin:
object EmailIdUtility {
fun isValid(email: String): Boolean {
val regex =
"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"
val pattern = Pattern.compile(regex)
val m = pattern.matcher(email)
return m.matches()
}
}
Run Code Online (Sandbox Code Playgroud)
然后将其转换EmailIdValidatorTest为 Kotlin
@RunWith(value = Parameterized::class)
class EmailIdValidatorTest(
private val email: String,
private val expected: Boolean)
{
@Test
fun testIsValidEmailId() {
val actual = EmailIdUtility.isValid(email)
assertEquals(expected, actual)
}
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{index}: isValid({0})={1}")
fun data(): Iterable<Array<Any>> {
return arrayListOf(
arrayOf("mary@testdomain.com", true),
arrayOf("mary.smith@testdomain.com", true),
arrayOf("mary_smith123@testdomain.com", true),
arrayOf("mary@testdomaindotcom", false),
arrayOf("mary-smith@testdomain", false),
arrayOf("testdomain.com", false)
).toList()
}
}
}
Run Code Online (Sandbox Code Playgroud)
记得
@JvmStatic在data()方法中添加,否则会报错:java.lang.Exception: No public static parameters method on class com.example.testapp.dev.EmailIdValidatorTest
更简单的方法
如果您可以使用另一个库(也可以在 Android 中使用),我建议您将JUnitParams添加到您的测试依赖项中,在 Android 中它可能是:
testImplementation "pl.pragmatists:JUnitParams:1.1.1"
Run Code Online (Sandbox Code Playgroud)
然后你可以用这种方式转换上面的类:
@RunWith(JUnitParamsRunner::class)
class EmailIdValidatorTest {
@Test
@Parameters(value = [
"mary@testdomain.com, true",
"mary.smith@testdomain.com, true",
"mary_smith123@testdomain.com, true",
"mary@testdomaindotcom, false",
"mary-smith@testdomain, false",
"testdomain.com, false"
])
fun testIsValidEmailId(email: String, expected: Boolean) {
val actual = EmailIdUtility.isValid(email)
assertEquals(expected, actual)
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说比JUnit方法容易得多。
有关如何使用 JUnitParams 的更多示例,您可以查看链接。
使用 JUnit 5,这要容易得多, 但如果您也不使用Android-JUnit 5,目前 Android 测试不支持JUnit 5。
我知道您正在使用 JUnit 4,但是如果您考虑更新到 JUnit 5,您可以使用@TestFactory注释来执行参数化单元测试。
在您的情况下,这将导致这样的测试类:
import org.junit.jupiter.api.DynamicTest
import org.junit.jupiter.api.TestFactory
internal class EmailIdValidatorTest {
@TestFactory
fun `test email id validity`() =
listOf(
"mary@testdomain.com" to true,
"mary.smith@testdomain.com" to true,
"mary_smith123@testdomain.com" to true,
"mary@testdomaindotcom" to false,
"mary-smith@testdomain" to false,
"testdomain.com" to false
).map {
dynamicTest("email ${it.first} should be ${if (it.second) "valid" else "not valid" }") {
val actual = EmailIdUtility.isValid(it.first)
assertEquals(expected, actual)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6335 次 |
| 最近记录: |