不能模拟 android.util.Patterns.EMAIL_ADDRESS.pattern()

Can't mock android.util.Patterns.EMAIL_ADDRESS.pattern()

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

我尝试了 mockkStatic(Patterns::class),但是 @Before 方法在应用规则 every { Patterns.EMAIL_ADDRESS.pattern() } returns EMAIL_REGEX_STRING.

时因 NPE 而崩溃

Class 我正在尝试测试:

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;
}}

您可以围绕它创建一个包装器,然后模拟或伪造该包装器,而不是直接使用 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()
}

或者创建一个 class 来包装它,也许是一个 PatternFactory class

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

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

尝试使用

PatternsCompat.EMAIL_ADDRESS.pattern()

而不仅仅是

Patterns.EMAIL_ADDRESS.pattern()

这对我有用。