![](/img/trans.png)
[英]How to mock android.util.Patterns with Mockito or MockK
[英]Mock android Patterns with mockito
我想用 Android 提供的一些代码验证电子邮件。
这是我要模拟的代码:
if(!Patterns.EMAIL_ADDRESS.matcher(email).matches())
throw new InvalidPhoneException(phone);
在我的测试文件中:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Patterns.class })
public class UserTest {
@Before
public void mockValidator() {
mockStatic(Patterns.class);
when(Patterns.EMAIL_ADDRESS.matcher(any(String.class)).matches()).thenReturn(true);
}
启动测试时出现此错误:
java.lang.NullPointerException
at ch.mycompany.myapp.model.UserTest.mockValidator(UserTest.java:59)
编辑 1:
我试过 :
mockStatic(Patterns.class);
Field field = PowerMockito.field(Patterns.class, "EMAIL_ADDRESS");
field.set(Patterns.class, mock(Pattern.class));
// prepare matcher
Matcher matcher = mock(Matcher.class);
when(matcher.matches())
.thenReturn(true);
// final mock
when(Patterns.EMAIL_ADDRESS.matcher(any(String.class)))
.thenReturn(matcher);
但是当我这样做时,我的代码 (Patterns.EMAIL_ADDRESS.matcher(email).matches()) 总是返回 false。 这令人困惑。
在这种特殊情况下,没有必要用 mockito 模拟 Patterns 类(无论如何它是不可模拟的),只需按如下方式更改源代码:
if(!Patterns.EMAIL_ADDRESS.matcher(email).matches())
throw new InvalidPhoneException(phone);
应该
if(!PatternsCompat.EMAIL_ADDRESS.matcher(email).matches())
throw new InvalidPhoneException(phone);
那为我完成了工作。
您正在执行电子邮件字段的验证
当返回 true 或 false 时,您不是在嘲笑这里的行为。 还要注意我们不能模拟最终类(模式)。
当正则表达式模式与返回 true 或 false 的值匹配时
而不是把事情复杂化。 只需通过传递值来执行验证。
解决方案1:
@Test
public void test() throws Exception{
String email="hello@gmail.com";
System.out.println(Patterns.EMAIL_ADDRESS.matcher(email).matches());
}
protected static class Patterns{
private static final String EMAIL_PATTERN =
"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
private static final Pattern EMAIL_ADDRESS=Pattern.compile(EMAIL_PATTERN);
}
output :
true
解决方案 2:模拟 Matcher 行为以返回 true 或 false
@RunWith(PowerMockRunner.class)
@PrepareForTest({Pattern.class,Matcher.class})
public class TestEmailPattern {
@Test
public void test() throws Exception{
String email="hello@gmail.com";
Pattern pattern=PowerMockito.mock(Pattern.class);
Matcher matcher=PowerMockito.mock(Matcher.class);
PowerMockito.when(matcher.matches()).thenReturn(true);
assertEquals(Patterns.EMAIL_ADDRESS.matcher(email).matches(),true);
}
protected static class Patterns{
private static final String EMAIL_PATTERN =
"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
private static final Pattern EMAIL_ADDRESS=Pattern.compile(EMAIL_PATTERN);
}
}
在这种情况下,使用Robolectric将为您省去很多麻烦。
而不是模拟模式,您应该获得预期的输出。
所以我建议使用Robolectric
代码段如下:
import android.os.Build;
import android.util.Patterns;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Build.VERSION_CODES.P)
public class ExampleUnitTest {
@Test
public void mobileNumber_passedValidNumber_success() {
assertThat(Patterns.PHONE.matcher("+919895123456").matches()).isTrue();
}
@Test
public void mobileNumber_passedInvalidNumber_error() {
assertThat(Patterns.PHONE.matcher("+91+9895123456").matches()).isFalse();
}
@Test
public void email_passedValidEmail_success() {
assertThat(Patterns.EMAIL_ADDRESS.matcher("android.developer@gmail.com").matches()).isTrue();
}
@Test
public void email_passedInvalidEmail_error() {
assertThat(Patterns.EMAIL_ADDRESS.matcher("android.developer@gmail.com@in").matches()).isFalse();
}
}
如果可以解决您的问题,请进行投票。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.