美文网首页
Jmockit(二): 场景应用

Jmockit(二): 场景应用

作者: halfempty | 来源:发表于2018-11-13 22:15 被阅读0次

    1 概述

    使用jmockit的目的,在于剥离代码间的依赖

    比如A方法引用B方法,B方法读取数据库返回一条记录,此时要测试A方法,需要保证B方法正常,不仅要搭建数据库环境,还要配置连接参数,还要在数据库中准备测试数据;而且运行失败并不能直接确定是A方法的问题,可能是B方法错误,或者数据库异常

    如果使用jmockit模拟B方法,便省去一系列的麻烦,安心地测A方法即可

    2 基本场景

    下面使用jmockit模拟static方法、普通方法、私有方法等

    public class App {
        public static String static_method() {
            return "static method";
        }
    
        public String normal_method() {
            return "normal method";
        }
    
        public final String final_method() {
            return "final method";
        }
    
        private String private_method() {
            return "private method";
        }
    
        @Test
        public void testApp() {
            App app = new App();
    
            new Expectations(App.class) {
                {
                    App.static_method();
                    result = "static method has been mocked";
    
                    app.normal_method();
                    result = "normal method has been mocked";
    
                    app.final_method();
                    result = "final method has been mocked";
                }
            };
    
            new MockUp<App>(App.class) {
                @Mock
                String private_method() {
                    return "private method has been mocked";
                }
            };
    
            System.out.println(App.static_method());
            System.out.println(app.normal_method());
            System.out.println(app.final_method());
            System.out.println(app.private_method());
        }
    }
    -------------------
    static method has been mocked
    normal method has been mocked
    final method has been mocked
    private method has been mocked
    

    3 带参数的方法

    3-1 指定相同实参

    当方法含有参数时,可以在mock过程中传入相同参数

    public class App {
        public String say(String name) {
            return "Hello " + name;
        }
    
        @Test
        public void testApp() {
            App app = new App();
    
            new Expectations(App.class) {
                {
                    app.say("Mark");
                    result = "Hello World";
                }
            };
    
            System.out.println(app.say("Mark"));  // Hello World
            System.out.println(app.say("Jack"));  // Hello Jack
        }
    }
    
    

    3-2 万能参数

    如果想mock任意实参,可能使用万能参数any

    可供组合的类型还有anyString, anyInt, anyBoolean, anyFloat等,表示任意该类型数据

    public class App {
        public String say(String name) {
            return "Hello " + name;
        }
    
        @Test
        public void testApp() {
            App app = new App();
    
            new Expectations(App.class) {
                {
                    app.say(anyString);
                    result = "Hello World";
                }
            };
    
            System.out.println(app.say("Mark"));  // Hello World
            System.out.println(app.say("Jack"));  // Hello World
        }
    }
    

    3-3 根据参数决定结果

    如果想根据不同的参数,返回不同的结果,可以使用Delegate类,附加一个自定义方法,方法名不一定非得delegate,随意指定

    public class App {
        public String say(String name) {
            return "Hello " + name;
        }
    
        @Test
        public void testApp() {
            App app = new App();
    
            new Expectations(App.class) {
                {
                    app.say(anyString);
                    result = new Delegate() {
                        String delegate(String name) {
                            if (name.length() > 5) {
                                return "Hello World";
                            } else {
                                return "Goodbye";
                            }
                        }
                    };
                }
            };
    
            System.out.println(app.say("Mark"));  //Goodbye
            System.out.println(app.say("Sophia"));  //Hello World
        }
    }
    

    3-4 部分参数mock,其他按原方法调用

    这里我们使用了MockUp<> 和 @Mock组合,并且在mock方法中加了一个新的对象invocation

    invocation.proceed方法,负责对原始方法的调用

    public class App {
        public String say(String name) {
            return "Hello " + name;
        }
    
        @Test
        public void testApp() {
            App app = new App();
    
            new MockUp<App>(App.class) {
                @Mock
                String say(Invocation invocation, String name) {
                    if (name.length() > 5) {
                        return "Hello World";
                    }
                    return invocation.proceed(name);
                }
            };
    
            System.out.println(app.say("Mark"));  // Hello Mark
            System.out.println(app.say("Jack"));  // Hello Jack
            System.out.println(app.say("Sophia"));  // Hello World
        }
    }
    

    4 Mock clinit/init初始化

    有时静态块,或者类的构造函数内有外部依赖的初始化操作,使用下面的方法实现mock

    public class App {
        public static int count = 1;
    
        static {
            count += 10;
        }
    
        public App() {
            count += 100;
        }
    }
    ----------------
    public class AppTest {
        @Test
        public void testApp() {
            new MockUp<App>(App.class) {
                @Mock
                void $clinit() {}
    
                @Mock
                void $init() {}
            };
    
            App app = new App();
            System.out.println(App.count); // 0
        }
    }
    

    相关文章

      网友评论

          本文标题:Jmockit(二): 场景应用

          本文链接:https://www.haomeiwen.com/subject/bberfqtx.html