Как создать параметризованные тестовые случаи в JUnit 4 и Kotlin для Android? - PullRequest
0 голосов
/ 20 марта 2019

Мне нужно что-то похожее на сценарий 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)));
    }
}

Так что же является правильным способомнаписать параметризованные тесты Kotlin с JUnit?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Я знаю, что вы используете 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)
            }
        }

}
0 голосов
/ 20 марта 2019

Следуя этому удивительному учебнику, мы можем реализовать его на языке 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()
    }
}

Затем конвертируйте EmailIdValidatorTest в Котлин

@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()
        }
    }
}

Не забудьте добавить @JvmStatic в метод data(), в противном случае вы получите сообщение об ошибке: java.lang.Exception: нет метода открытых статических параметров для класса com.example.testapp.dev.EmailIdValidatorTest


ПРОСТОЙ ПУТЬ

Если вы можете использовать другую библиотеку (также работающую в Android), я предлагаю вам добавить JUnitParams к вашим тестовым зависимостям, в Android это может быть:

testImplementation  "pl.pragmatists:JUnitParams:1.1.1"

Тогда вы можете преобразовать вышеуказанный класс следующим образом:

@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)
    }
}

, что для меня намного проще, чем JUnit.

Дополнительные примеры использования JUnitParams вы можете посмотреть по ссылке.

С JUnit 5 это намного проще но в настоящее время JUnit 5 не поддерживается для тестов Android, если вы этого не сделаете используйте Android-JUnit 5 тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...