JMockit简单使用

JMockit是google code上面的一个java单元测试的mock框架。


JMockit涉及到的元素介绍:

@Tested和@Injectable
     对@Tested对象判断是否为null,是则通过合适构造器初始化, @Injectable的实例会自动注入到@Tested中。

@Mocked
     @Mocked修饰的实例,将会把实例对应类的所有实例的所有行为都mock掉(无论构造方法,还是private,protected方法)。

Expectations
     录制期望发生行为的块,一般由Expectations类和NonStrictExpectations类定义,用Expectations类定义的,则mock对象在运行时只能按照 Expectations块中定义的顺序依次调用方法,不能多调用也不能少调用,所以可以省略掉Verifications块;而用NonStrictExpectations类定义的,则没有这些限制,所以如果需要验证,则要添加Verifications块。result和times都是其内定成员变量。result可以重定义录制行为的返回值甚至通过Delegate来重定义行为,times是期待录制行为的发生次数。在Expectations中发生的调用,均会被mock。

Deencapsulation
     用于Mock私有方法和私有属性。

简单示例:
package com.zero.jmockit;

public class Utils {
	private static String URL_STRING = "http://www.sina.com.cn";

	private static void deal() {
		System.out.println("deal() " + URL_STRING);
	}

	public static String getObject(JMockitObject object, String str) {
		deal();
		System.out.println("getObject() ");
		return URL_STRING + str;
	}
}
package com.zero.jmockit;

public class UserService {
	public String getUserName(int id) {
		return "hello";
	}
}
package com.zero.jmockit;

import javax.annotation.Resource;

public class JMockitObject {

	@Resource
	private UserService userService;

	public void dealUser() {
		String name = userService.getUserName(1);
		System.out.println("userService.getUserName() : " + name);
		sys(name);
	}

	private void sys(String name) {
		System.out.println("sys() : " + name);
	}

	public String getString() {
		getObject(this, "/zero");
		return Utils.getObject(this, "/zero");
	}

	private void getObject(JMockitObject object, String str) {
		 System.out.println("--------");
	}

}
package com.zero.jmockit;

import org.junit.*;
import org.junit.runner.RunWith;

import mockit.*;
import mockit.integration.junit4.JMockit;

@RunWith(JMockit.class)
public final class JMockitTest {
	@Tested
	@Mocked
	private JMockitObject jMockitObject;

	@Injectable
	private UserService userService;

	@Test
	public void testDealUser() {
		new NonStrictExpectations() {// 录制预期模拟行为
			{
				userService.getUserName(anyInt);//mock public方法
				result = "zero";// 也可以使returns("zero");
				times = 1;

				Deencapsulation.invoke(jMockitObject, "sys", anyString);//mock private方法
				// sys()无返回值,没定义result,则调用的结果返回空,故result = null; 可写可不写
				result = null;
			}
		};
		jMockitObject.dealUser();//回放
	}

	@Test
	public void testSys() {
		Deencapsulation.invoke(jMockitObject, "sys", "Hello World!");//测试private方法
	}

	@Test
	public void testStaticField() {// mock 静态私有属性
		new NonStrictExpectations(Utils.class) {
			{
				Deencapsulation.setField(Utils.class, "URL_STRING",
						"www.baidu.com");
			}
		};
		// 第二种方式:
		// new MockUp<Utils>() {
		// {
		// // 修改静态私有属性
		// Deencapsulation.setField(Utils.class, "URL_STRING",
		// "www.baidu.com");
		// }
		// };
		String str = Deencapsulation.getField(Utils.class, "URL_STRING");
		Assert.assertEquals("www.baidu.com", str);
	}

	@Test
	public void testStaticFunction() {// mock 静态私有方法
		new MockUp<Utils>() {
			@Mock
			private void deal() {// 注意在MockUp中的方法除了不包含static关键字以外,其他都和被Mock的方法签名相同,并且使用@Mock标注
				System.out.println("mock deal() ");
			}
		};
		Deencapsulation.invoke(Utils.class, "deal");
	}

	@Test
	public void testGetString() {
		new NonStrictExpectations() {
			{
				Deencapsulation.invoke(jMockitObject, "getObject",
						withAny(JMockitObject.class), withAny(String.class));// 不能使用any这样的参数,否则必须使用正确类型的参数;
				// withAny(JMockitObject.class), anyString); 可以
			}
		};
		new NonStrictExpectations(Utils.class) {
			{
				Utils.getObject((JMockitObject) any, anyString);
				returns("zero");
			}
		};

		Assert.assertEquals("zero", jMockitObject.getString());
	}
}



你可能感兴趣的:(JMockit简单使用)