java mock进行单元测试

本文通过一些java mock测试的例子简单讲解一下如何使用java mock进行测试。

1.准备工作

a.基于maven在pom.xml中添加如下依赖(包含了mock以及powermock):

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.9.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.0.42-beta</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>1.6.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>1.6.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-testng</artifactId>
            <version>1.6.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>  
            <groupId>commons-lang</groupId>  
            <artifactId>commons-lang</artifactId>  
            <version>2.6</version>  
            <scope>provided</scope>  
        </dependency>
  </dependencies>

b.建立Controller类(主要功能是字符串解析并返回或者封装结果):

package com.zhq.controller;

import java.util.HashMap;
import java.util.Map;

import com.zhq.bean.PersonInfo;
import com.zhq.common.CommonUtils;
import com.zhq.dao.PersonQueryDao;

public class InfoController {
    /**
     * 负责将parameters中的key1:value1,key2:value2的数据解析并放置到result中
     * @param parameters
     * @param keys
     * @return
     */
    public Map<String, String> packageInfos(String parameters, String... keys) {
        Map<String, String> result = new HashMap<String, String>();
        if (CommonUtils.verifyParameters(result, parameters, keys)) {
            return result;
        }
        return null;
    }
    
    /**
     *
     * 负责判断参数的合法性并将参数内容封装到PersonInfo中
     * @param name
     * @param age
     * @return
     */
    public PersonInfo packageIntoPerson(String name, String age) {
        PersonQueryDao dao = new PersonQueryDao();
        return dao.query(name, age);
    }

}

c.Controller类中使用的公共类CommonUtils:

package com.zhq.common;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

public class CommonUtils {
    
    /**
     * 负责将parameters中的key1:value1,key2:value2的数据解析并放置到result中
     * @param result 解析后的结果Map
     * @param parameters 要解析的参数
     * @param keys 要解析的key
     * @return
     */
    public static boolean verifyParameters(Map<String, String> result,
            String parameters, String...keys) {
        Map<String, String> parameterMap = new HashMap<String, String> ();
        if (StringUtils.isBlank(parameters) || keys == null || keys.length == 0) {
            return false;
        }
        String[] splitParameters = parameters.split(",");
        String oneSplitted[] = null;
        for (String splitted : splitParameters) {
            oneSplitted = splitted.split(":");
            if (oneSplitted.length < 2) continue;
            parameterMap.put(oneSplitted[0], oneSplitted[1]);
        }
        for (String key : keys) {
            if (!parameterMap.containsKey(key)) {
                return false;
            }
            result.put(key, parameterMap.get(key));
        }
        return true;
    }

}

d.Controller类中使用的查询类PersonQueryDao:

package com.zhq.dao;

import org.apache.commons.lang.StringUtils;
import com.zhq.bean.PersonInfo;

public class PersonQueryDao {
    
    
    /**
     * 跟据名字和年龄查询并返回个人信息
     * @param name
     * @param age
     * @return
     */
    public PersonInfo query(String name, String age) {
        if(StringUtils.isEmpty(name) || StringUtils.isEmpty(age)) {
            return null;
        }
        PersonInfo person = new PersonInfo();
        person.setName(name);
        person.setAge(age);
        return person;
    }

}

e.Controller中使用的bean类PersonInfo:

package com.zhq.bean;

public class PersonInfo {
    
    private String name;
    
    private String age;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    public void setAge(String age) {
        this.age = age;
    }
    
    public String getAge() {
        return this.age;
    }

}

2.对InfoController类进行测试(测试代码在src/test/java中)

主要包含的知识点是:如何对调用静态方法的类进行mock;如何注入mock,并进行真实调用;如何使用mock来模拟调用对象中的函数;如何在mock测试中使用反射机制将结果填入参数中。测试代码如下:

package com.zhq.controller;


import java.util.Map;

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.zhq.bean.PersonInfo;
import com.zhq.common.CommonUtils;
import com.zhq.dao.PersonQueryDao;

//对于测试过程中使用到static函数的调用,先将调用static函数的类准备好
@PrepareForTest({ CommonUtils.class })
public class InfoControllerTest extends PowerMockTestCase {
    
    //注入式的mock,用于真实调用
    @InjectMocks
    private InfoController infoController = new InfoController();
    
    //使用@Mock模拟调用对象中的函数
    @Mock
    private PersonQueryDao personDao;
    
    /**
     * 测试InfoController中的packageInfos
     */
    @Test
    public void packageInfosTest() {
        //在函数调用中使用CommonUtils类的静态方法需要先mockStatic一下CommonUtils
        PowerMockito.mockStatic(CommonUtils.class);
        //测试返回结果为空
        Mockito.when(CommonUtils.verifyParameters(Mockito.anyMapOf(String.class, String.class), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(false);
        Assert.assertEquals(infoController.packageInfos("name:zhq,age:30", "name", "age"), null);
        //测试返回结果非空
        //因为要模拟将CommonUtils.verifyParameters的结果放入Map中并返回,所以使用thenAnswer采用反射的方式将结果填入
        Mockito.when(CommonUtils.verifyParameters(Mockito.anyMapOf(String.class, String.class), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<Boolean>() {
                      public Boolean answer(InvocationOnMock invocation) throws Throwable {
                            @SuppressWarnings("unchecked")
                            Map<String,String> result = (Map<String,String>) invocation.getArguments()[0];
                            result.put("name", "zhq");
                            result.put("age", "30");
                            return true;
                      }
                      });
        Map<String,String> result = infoController.packageInfos("name:zhq,age:30", "name", "age");
        Assert.assertEquals(result.get("name"), "zhq");
        Assert.assertEquals(result.get("age"), "30");
    }
    
    /**
     * 测试InfoController中的packageIntoPerson
     */
    @Test
    public void packageIntoPersonTest() {
        //测试返回null
        Mockito.when(personDao.query(Mockito.anyString(), Mockito.anyString())).thenReturn(null);
        Assert.assertEquals(infoController.packageIntoPerson("zhq", null), null);
        //测试返回非null
        Mockito.when(personDao.query(Mockito.anyString(), Mockito.anyString())).thenReturn(new PersonInfo());
        Assert.assertNotNull(infoController.packageIntoPerson("zhq", "age"));
    }

}

3.对CommonUtils类进行测试(测试代码在src/test/java中)

主要包含的知识点是:怎样对静态函数进行测试

package com.zhq.common;

import java.util.HashMap;
import java.util.Map;

import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.Test;

public class CommonUtilsTest extends PowerMockTestCase {

    @Test
    public void verifyParametersTest() {
        Map<String,String> result = new HashMap<String,String> ();
        //测试parameters为null
        Assert.assertEquals(CommonUtils.verifyParameters(result, null, "abc"), false);
        //测试keys为null
        Assert.assertEquals(CommonUtils.verifyParameters(result, "name:zhq,age:30",  null), false);
        //测试keys为""
        Assert.assertEquals(CommonUtils.verifyParameters(result, "name:zhq,age:30", ""), false);
        //测试parameters中的键值与keys不匹配
        Assert.assertEquals(CommonUtils.verifyParameters(result, "name:zhq,age:30", "name,height"), false);        
        //测试parameters中的键值与keys不匹配
        Assert.assertEquals(CommonUtils.verifyParameters(result, "name:zhq,age:30", "name"), true);
        Assert.assertEquals(result.get("name"), "zhq");
    }
}

转载于:https://my.oschina.net/seektechnology/blog/869004

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值