美文网首页程序员
Mockito入门及配合Junit进行单元测试

Mockito入门及配合Junit进行单元测试

作者: 唐影若凡 | 来源:发表于2017-11-17 14:03 被阅读0次

    声明:原创文章,转载请注明出处。http://www.jianshu.com/p/46afe8c54d34

    一、背景

    最近一段时间在给写的框架补单元测试。发现有一些方法做单元测试不好做,主要是其内部依赖了许多外部环境,如Zookeeper、DB、Http请求等等。
    如果为了这些单元测试单独去搞一套环境,很是费事。再者代码每天在Jenkins上跑单元测试,环境不一定相通。

    如果您面临上述相同的问题,可以继续向下看。


    Mock示例

    二、一个例子

    2.1 需要做单元测试的代码

    假设我们有下面这样一个类,其中的isAdmin方法主要是从redis中获取数据,然后进行对比判断。现实中,这里可能有很多复杂的逻辑,这里只做抛砖引玉。

    public class RedisDemo {
        private Jedis jedis;
    
        public void setUp() {
            jedis = new Jedis("127.0.0.1", 6379);
            jedis.connect();
        }
    
        public boolean isAdmin(String user) {
            String ret = jedis.get("name");
            if (ret.equals(user)) {
                return true;
            }
            return false;
        }
    
        public static void main(String[] args) {
            RedisDemo demo = new RedisDemo();
            demo.setUp();
            boolean isAdmin = demo.isAdmin("test");
            System.out.println(isAdmin);
        }
    }
    

    2.2 单元测试

    @Test
        public void test() {
            RedisDemo redisDemo = new RedisDemo();
            redisDemo.setUp("127.0.0.1", 6379);
            Assert.assertSame(true, redisDemo.isAdmin("admin"));
        }
    

    我们通常使用上述的代码对其进行单元测试,看似简单。但是需要我们搭建一套redis环境,并且初始化数据。如果只有redis还好,假如项目中依赖的外部环境有ZK、redis、MySQL、http还有其他部门的一些接口,在这样做的话,其他不说,光维护这一套环境就很麻烦了。

    那应该怎么简化操作呢?继续向下看。

    三、使用Mockito进行测试

    3.1 引入依赖

        <dependencies>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
                <version>1.8.5</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    

    3.2 编写单元测试

    public class RedisTest {
        @Rule
        public ExpectedException exception = ExpectedException.none(); // 不允许有异常
        
        @Test
        public void mockTest() throws Exception {
            Jedis mockJedis = Mockito.mock(Jedis.class);
            Mockito.when(mockJedis.get("name")).thenReturn("admin");
    
            RedisDemo redisDemo = new RedisDemo();
            Field daoField = redisDemo.getClass().getDeclaredField("jedis");
            daoField.setAccessible(true);
            daoField.set(redisDemo, mockJedis);
    
            Assert.assertSame(true, redisDemo.isAdmin("admin"));
        }
    }
    

    这里使用了Mockito.mock()这个API进行Mock,当程序调用jedis的方法时,并不会真正触发jedis的方法,而是返回一个设定的值。

    四、总结

    本文只是对模块构造很复杂的测试,分享了一个工具。当然,Mockito的功能不仅仅如此,更详细的文档请参考:
    https://static.javadoc.io/org.mockito/mockito-core/2.11.0/org/mockito/Mockito.html

    相关文章

      网友评论

        本文标题:Mockito入门及配合Junit进行单元测试

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