单元测试,早些年时常听到这个概念,真的有去做的确实少,基本都是自己功能上的测试,开发完测试跑一边没啥问题就发布了。这几天花了点心思看了下MockIto框架,记录博文。

  • MockIto官网文档在https://static.javadoc.io/org.mockito/mockito-core/2.23.0/org/mockito/Mockito.html。
  • MockIto框架是基于原生JUnit4,JUnit4是整个单元测试的基础,他能够帮我我们开发者更快,更高效的进行单元测试

1.在mvp的模式上,我们建立一个P层叫LuckinTestPresenter,大概流程为:注册-》验证此账号是否允许注册,允许-》注册成功,具体为

/**
     * 注册账号密码
     * @param phone 账号
     * @param passWord 密码
     */
    public void register(String phone, String passWord) {
         System.out.println("到达register");
    }
    /**
     * 验证是否可以注册
     * @param phone
     * @param passWord
     */
    public void verification(String phone, String passWord) {
        System.out.println("到达verification");
        if (!isLimit()) {
            register(phone, passWord);
        }
    }
    /**
     * 注册之前检查这个手机号是否被限制
     * @return
     */
    public boolean isLimit() {
        return false;
    }

2:我们现在要在单元测试中,验证点击注册的时候程序是否有跑过verification方法,那么我们的单元测试案例为

public class LuckinPresenterTest {
    @Test
    public void check() {
        //mockito会模拟LoginPresenterTest这个需要测试的class,返回一个LoginPresenterTest对象
        LuckinTestPresenter luckinTestPresenter = Mockito.mock(LuckinTestPresenter.class);
        //主动调用验证方法
        luckinTestPresenter.verification("2018091280", "word");
        //现在我们要了利用MockIto验证程序到这为止,是否走到了register(),方法如下
        Mockito.verify(luckinTestPresenter).register("2018091280", "word");
    }
}

run发现报错

android app 单元测试 android单元测试框架_移动开发


为啥呢,因为你要验证的register()并没有被调用,为啥呢,看程序,应该执行的呀,这里需要注意的就是所哟Mock标记的类都是虚拟的,返回值都是null,也就是说你无法用一个为null的对象去调用register方法。如果我就要这么做呢,那就用spy标注吧。修改案例改为:

public class LuckinPresenterTest {
    @Test
    public void check() {
        //mockito会模拟LoginPresenterTest这个需要测试的class,返回一个LoginPresenterTest对象
        LuckinTestPresenter luckinTestPresenter = Mockito.spy(LuckinTestPresenter.class);
        //主动调用验证方法
        luckinTestPresenter.verification("2018091280", "word");
        //现在我们要了利用MockIto验证程序到这为止,是否走到了register(),方法如下
        Mockito.verify(luckinTestPresenter).register("2018091280", "word");
    }
}

run结果为-》成功

android app 单元测试 android单元测试框架_移动开发_02


2:现在有一个需求,我要测试当我isLimit()返回都会true时程序有没有走register,我又不想动原p层代码,那咋办呢,有办法,我们修改为

public class LuckinPresenterTest {
    @Test
    public void check() {
        //mockito会模拟LoginPresenterTest这个需要测试的class,返回一个LoginPresenterTest对象
        LuckinTestPresenter luckinTestPresenter = Mockito.spy(LuckinTestPresenter.class);
        //主动调用验证方法
        Mockito.when(luckinTestPresenter.isLimit()).thenReturn(true);//控住islimit返回true
        luckinTestPresenter.verification("2018091280", "word");
        //现在我们要了利用MockIto验证程序到这为止,是否走到了register(),方法如下
        Mockito.verify(luckinTestPresenter).register("2018091280", "word");
    }
}

run结果为

android app 单元测试 android单元测试框架_移动开发_03


程序走过了verification,之后报错(就说明mock验证失败,程序没有走到register方法,因为你已经把isLimit返回值设为了true)。

相关方法为:

public class LuckinPresenterTest {
    @Test
    public void check() {
        //mockito会模拟LoginPresenterTest这个需要测试的class,返回一个LoginPresenterTest对象
        LuckinTestPresenter luckinTestPresenter = Mockito.spy(LuckinTestPresenter.class);

        //控住isTourise返回true
        Mockito.when(luckinTestPresenter.isLimit()).thenReturn(true);

        //主动验证操作
        luckinTestPresenter.verification("2018091280", "word");

        //现在我们要了利用MockIto验证程序到这为止,是否走到了register(),方法如下
        Mockito.verify(luckinTestPresenter).register("2018091280", "word");

        //验证register的方法是否调用,并且是否为1次,并且参数一致
        Mockito.verify(luckinTestPresenter, Mockito.times(1)).register("2018091280", "word");

        //验证register的方法从未调用过
        Mockito.verify(luckinTestPresenter, Mockito.never()).register("2018091280", "word");

        //验证register的方法是否调用,并且是否为1次,参数忽略
        Mockito.verify(luckinTestPresenter, Mockito.times(1)).register(Mockito.anyString(), Mockito.anyString());

    }
}


转载于:https://blog.51cto.com/8912823/2310217