繁体   English   中英

使用 mockito 模拟 android 模式

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM