6

目前我正在使用 MockK 库(版本 1.8.1)在 Android Dev 中进行单元测试,我的问题是我无法模拟 Patterns.EMAIL_ADDRESS。每次调用此属性时,测试用例都会抛出 NPE。

我试过mockkStatic(Patterns::class)了,但 @Before 方法在应用规则时会因 NPE 而崩溃every { Patterns.EMAIL_ADDRESS.pattern() } returns EMAIL_REGEX_STRING

我正在尝试测试的课程:

public class EmailValidator {

private static final String EMPTY = "";
private final Context context;

@Inject
public EmailValidator(Context context) {
    this.context = context;
}

public String isValidEmail(String email) {
    if (StringUtils.isEmpty(email)) {
        return context.getString(R.string.sign_up_error_email_empty);
    }

    if (!email.matches(Patterns.EMAIL_ADDRESS.pattern())) {
        return context.getString(R.string.sign_up_error_email_validate);
    }
    return EMPTY;
}}
4

2 回答 2

25

尝试使用

PatternsCompat.EMAIL_ADDRESS.pattern()

而不仅仅是

Patterns.EMAIL_ADDRESS.pattern()

这为我完成了工作。

于 2019-06-10T19:27:28.880 回答
1

Patterns.EMAIL_ADDRESS您可以围绕它创建一个包装器,然后模拟或伪造包装器,而不是直接使用。

包装器可以是一种方法,例如:

class EmailValidator {
    fun isValidEmail(email: String) {
        if (StringUtils.isEmpty(email)) {
            return context.getString(R.string.sign_up_error_email_empty);
        }

        if (!email.matches(getEmailPattern())) {
            return context.getString(R.string.sign_up_error_email_validate);
        }
    }

    private fun getEmailPattern(): String = Patterns.EMAIL_ADDRESS.pattern()
}

你的测试可以像这样模拟它:

@Test
fun `test email validator`() {
    val validator = spyk(EmailValidator())

    every { validator["getEmailPattern"]() } returns yourTestPattern

    assertThat(validator.isValidEmail("blah blah blah")).isFalse()
}

或者创建一个包装它的类,也许是一个 PatternFactory 类

class PatternFactory {
    fun getEmailPattern(): String = ...
    fun getVinPattern(): String = ...
}

PatternFactory然后作为依赖项传入并模拟它以进行测试

于 2018-07-13T01:04:41.437 回答