java单元测试mock_java mock进行单元测试

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

1.准备工作

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

org.testng

testng

6.9.10

test

org.mockito

mockito-core

2.0.42-beta

test

org.powermock

powermock-core

1.6.5

test

org.powermock

powermock-api-mockito2

1.6.5

test

org.powermock

powermock-module-testng

1.6.5

test

commons-lang

commons-lang

2.6

provided

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 packageInfos(String parameters, String... keys) {

Map result = new HashMap();

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 result,

String parameters, String...keys) {

Map parameterMap = new HashMap ();

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() {

public Boolean answer(InvocationOnMock invocation) throws Throwable {

@SuppressWarnings("unchecked")

Map result = (Map) invocation.getArguments()[0];

result.put("name", "zhq");

result.put("age", "30");

return true;

}

});

Map 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 result = new HashMap ();

//测试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");

}

}


版权声明:本文为weixin_42361283原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。