Mockito的简单实践

来源:互联网 发布:计天数的软件 编辑:程序博客网 时间:2024/05/29 03:11

一、简要概念:

1.Mock的概念:mock就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象
2.目的:
    ①验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等 
    ②可以随时指定mock对象的某个方法返回什么样的值,或执行什么样的动作。
    Mockito.verify(mockUserManager, Mockito.times(3)).performLogin(...);
    Mockito.when(mock.verifyPassword(anyString())).thenReturn(true);

 3.要使用mock,一般需要使用mock框架,目前安卓最常用的有两个,Mockito和JMockit。两者的区别是,前者不能mock static method和final class、final method,后者可以。

二、环境配置:

      testCompile "org.mockito:mockito-core:1.10.19"

三、测试demo,一切尽在代码中

 class LoginPresenter {    private String userName;    LoginView view = new LoginView();    public void login(String name, String pwd){      view.performLogin( name, pwd );    }    public String getUserName(){        return userName;    }    public void setUserName(String name){        this.userName = name;    }    public String getServerData (String param){        return  "服务器数据";    }    public void setView( LoginView view){        this.view = view;    }     void privateMethod(String name, String pwd){        view.performLogin( name, pwd );    }    public void buttonClickCallback(){        view.setOnFcButtonClickListener(new LoginView.OnFcButtonClickListener() {            @Override            public void onFcButtonClick(int n) {                if (n == 1) {                    view.performLogin("fc","111");                }            }        });    }
public class LoginView {    public interface OnFcButtonClickListener {        void onFcButtonClick(int n);    }    private OnFcButtonClickListener onfcButtonClickListener;    public void setOnFcButtonClickListener(OnFcButtonClickListener listener){        this.onfcButtonClickListener = listener;    }    public LoginView() {    }    public void performLogin(String name, String pwd){    }    public void buttonClickCallback(int n){        onfcButtonClickListener.onFcButtonClick(n);    }}
mockito的用法的简单例子
public class LoginPresenterTest {    private LoginView mockLoginView;    private LoginPresenter presenter;    @Before    public void setUp() throws Exception {        mockLoginView = Mockito.mock(LoginView.class);        presenter = new LoginPresenter();    }    /**     * 方法描述:测试 LoginPresenter的login()方法是否调用LoginView的performLogin()方法     * 期待结果:被调用,且参数正常     *     * 注意:mock出来的对象并不会自动替换掉正式代码里面的对象,你必须要有某种方式把mock对象应用到正式代码里面     *     * @throws Exception     */    @Test    public void login() throws Exception {        presenter = new LoginPresenter();        presenter.setView(mockLoginView);        presenter.login("fc","111");        Mockito.verify(mockLoginView).performLogin("fc","111");//        Mockito.verify(mockLoginView).performLogin("大大","111");    }    /**     * 方法描述:是否至少调用一次某个方法     * 期待结果: 是     *     * @throws Exception     */    @Test    public void login_atLeastOnce() throws Exception {        presenter.setView(mockLoginView);        presenter.login("fc","111");        Mockito.verify(mockLoginView,Mockito.atLeastOnce()).performLogin("fc","111");    }    /**     * 方法描述:测试是否调用了两次     * 期待结果: 是     *     * @throws Exception     */    @Test    public void login_twice() throws Exception {        presenter.setView(mockLoginView);        presenter.login("fc","111");        presenter.login("fc","111");        Mockito.verify(mockLoginView,Mockito.times(2)).performLogin("fc","111");    }    /**     * 指定mock对象的某个方法返回特定的的值     */    @Test    public void getServerData_Specify(){        String value = "小小";        LoginPresenter mockPresenter = Mockito.mock(LoginPresenter.class);        Mockito.when(mockPresenter.getServerData(Mockito.anyString())).thenReturn(value);        Assert.assertEquals(mockPresenter.getServerData("你好"),value);    }    /**     * 调用一次返回不同的值     */    @Test    public void getServerData_differValue(){        String value = "ZhangSan";        String secondValue = "LiSi";        LoginPresenter mockPresenter = Mockito.mock(LoginPresenter.class);        Mockito.when(mockPresenter.getServerData(Mockito.anyString())).thenReturn(value).thenReturn(secondValue);        Assert.assertEquals(mockPresenter.getServerData("你好"),value);        Assert.assertEquals(mockPresenter.getServerData("你好+1"),secondValue);    }    /**     * mock和spy 的区别:     * 使用Mock生成的类,所有方法都不是真实的方法,而且返回值都是NULL     * 使用Spy生成的类,所有方法都是真实方法,返回值都是和真实方法一样的。     *     * @throws Exception     */    @Test    public void getUserName() throws Exception{//        LoginPresenter spyPresenter = Mockito.mock(LoginPresenter.class);        LoginPresenter spyPresenter = Mockito.spy(LoginPresenter.class);        spyPresenter.setUserName("fc");        Assert.assertEquals("fc",spyPresenter.getUserName());    }    /**     *  测试私有方法: 去掉private     */    @Test    public void testPrivateMethod(){        presenter = new LoginPresenter();        presenter.setView(mockLoginView);        presenter.privateMethod("fc","111");        Mockito.verify(mockLoginView).performLogin("fc","111");    }    /**     *  测试接口回调,异步方法:     *  指定回调某种状态后,验证代码逻辑对不对     */    @Test    public void testCallBack(){        Mockito.doAnswer(new Answer() {            @Override            public Object answer(InvocationOnMock invocation) throws Throwable {                Object[] arguments = invocation.getArguments();                LoginView.OnFcButtonClickListener listener = (LoginView.OnFcButtonClickListener) arguments[0];                //模拟回调的状态  可以试试把1改为其他的值                listener.onFcButtonClick(1);                return null;            }        }).when(mockLoginView).setOnFcButtonClickListener(Mockito.any(LoginView.OnFcButtonClickListener.class));        presenter.setView(mockLoginView);        presenter.buttonClickCallback();        Mockito.verify(mockLoginView).performLogin(Mockito.anyString(),Mockito.anyString());    }