如今,我们的很多应用程序是基于Spring的,通过Spring IOC容器来管理我们的Java对象。所以这里单独提出对Spring Bean如何Mock方法。

以上述提到如何Mock类中的提到的AnOrdinaryClass为例,先把这个类配置在Spring的配置文件中

<?xml version="1.0" encoding="utf-8"?>
<!--suppress ALL -->
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
	default-autowire="byName">

   <!-- 1个普通的spring bean-->
	<bean id="anOrdinaryBean" class="cn.jmockit.demos.AnOrdinaryClass" /> 

</beans>



同样地讲述2种Mock方法

  1. 用Expectations来Mock。

  2. //用Expectations来Mock Spring Bean
    @ContextConfiguration(locations = { "/META-INF/applicationContext1.xml" })
    @RunWith(SpringJUnit4ClassRunner.class)
    public class SpringBeanMockingByExpectationsTest {
    	// 注入Spring Bean,Mock这个实例,就达到了Mock Spring Bean的目的
    	@Resource
    	AnOrdinaryClass anOrdinaryBean;
    
    	@Test
    	public void testSpringBeanMockingByExpectation() {
    		// 直接把实例传给Expectations的构造函数即可Mock这个实例
    		new Expectations(anOrdinaryBean) {
    			{
    				// 尽管这里也可以Mock静态方法,但不推荐在这里写。静态方法的Mock应该是针对类的
    				// mock普通方法
    				anOrdinaryBean.ordinaryMethod();
    				result = 20;
    				// mock final方法
    				anOrdinaryBean.finalMethod();
    				result = 30;
    				// native, private方法无法用Expectations来Mock
    			}
    		};
    		Assert.assertTrue(AnOrdinaryClass.staticMethod() == 1);
    		Assert.assertTrue(anOrdinaryBean.ordinaryMethod() == 20);
    		Assert.assertTrue(anOrdinaryBean.finalMethod() == 30);
    		// 用Expectations无法mock native方法
    		Assert.assertTrue(anOrdinaryBean.navtiveMethod() == 4);
    		// 用Expectations无法mock private方法
    		Assert.assertTrue(anOrdinaryBean.callPrivateMethod() == 5);
    	}
    
    	@BeforeClass    
    	// 加载AnOrdinaryClass类的native方法的native实现    
    	public static void loadNative() throws Throwable {    
    		JNITools.loadNative();    
    	}    
    }
  3. 用MockUp来Mock

//用MockUp来Mock Spring Bean
@ContextConfiguration(locations = { "/META-INF/applicationContext1.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringBeanMockingByMockUpTest {
	// 注入Spring Bean,Mock这个实例,就达到了Mock Spring Bean的目的
	@Resource
	AnOrdinaryClass anOrdinaryBean;

	@Test
	public void testSpringBeanMockingByMockUp() {
		// 静态方法被mock了
		Assert.assertTrue(AnOrdinaryClass.staticMethod() == 10);
		// 普通方法被mock了
		Assert.assertTrue(anOrdinaryBean.ordinaryMethod() == 20);
		// final方法被mock了
		Assert.assertTrue(anOrdinaryBean.finalMethod() == 30);
		// native方法被mock了
		Assert.assertTrue(anOrdinaryBean.navtiveMethod() == 40);
		// private方法被mock了
		Assert.assertTrue(anOrdinaryBean.callPrivateMethod() == 50);
	}

	@BeforeClass
	public static void beforeClassMethods() throws Throwable {
		loadNative();
		// 必须在Spring容器初始化前,就对Spring Bean的类做MockUp
		addMockUps();
	}

	    
	// 加载AnOrdinaryClass类的native方法的native实现    
	public static void loadNative() throws Throwable {    
		JNITools.loadNative();    
	}    

	// 对AnOrdinaryClass的Class
	public static class AnOrdinaryClassMockUp extends MockUp<AnOrdinaryClass> {
		// Mock静态方法
		@Mock
		public static int staticMethod() {
			return 10;
		}

		// Mock普通方法
		@Mock
		public int ordinaryMethod() {
			return 20;
		}

		@Mock
		// Mock final方法
		public final int finalMethod() {
			return 30;
		}

		// Mock native方法
		@Mock
		public int navtiveMethod() {
			return 40;
		}

		// Mock private方法
		@Mock
		private int privateMethod() {
			return 50;
		}
	}

	// 添加MockUp
	public static void addMockUps() {
		new AnOrdinaryClassMockUp();
	}
}