JMockit學習之mock介面和抽象類

aitangyong發表於2014-02-27

大型軟體專案,往往會在設計的時候進行模組化劃分,模組之間存在依賴關係。為了減少各個模組之間的耦合,通過介面進行依賴,各個模組由不同的開發組進行並行開發。如果A模組需要使用B模組的介面,但是B模組由於開發進度緩慢,並沒有完成對應實現類的開發。那麼這個時候A進行單元測試就有困難了。如果A需要測試自己的模組功能,就需要將B的介面進行mock。下面介紹下jmockit如何mock介面的。

package code.c1;

public interface IStudentService {
	public String getName(int id);

	public int getAge(int id);
}
package code.c1;

public abstract class AbstractStudentService {
	public String getName(int id) {
		return "ATY";
	}

	public abstract int getAge(int id);
}


下面是單元測試:

package net.aty.testtools.jmockit.c1;

import mockit.Mock;
import mockit.MockUp;

import org.junit.Assert;
import org.junit.Test;

import code.c1.AbstractStudentService;
import code.c1.IStudentService;

public class Run {

	@Test
	public void t1() {
		MockUp<IStudentService> proxyStub = new MockUp<IStudentService>() {
			// 需要使用@Mock標記,否則jmockit不會處理;
			// 而且方法的簽名必須與介面中方法簽名一致,否則jmockit會報錯
			@Mock
			public String getName(int id) {
				return "00" + id;
			}
		};

		IStudentService mockInstance = proxyStub.getMockInstance();

		Assert.assertEquals("001", mockInstance.getName(1));

		Assert.assertEquals(0, mockInstance.getAge(1));

		proxyStub.tearDown();
	}

	@Test
	public void t2() {
		MockUp<AbstractStudentService> proxyStub = new MockUp<AbstractStudentService>() {
			@Mock
			public int getAge(int id) {
				return 10 * id;
			}
		};

		AbstractStudentService mockInstance = proxyStub.getMockInstance();

		Assert.assertEquals("ATY", mockInstance.getName(1));

		Assert.assertEquals(10, mockInstance.getAge(1));

		proxyStub.tearDown();
	}

}

jmockit有如下特點:

1、如果目標介面中存在多個方法,我們只需要關注需要自己mock的方法即可,對於不需要的方法,jmockit會提法預設實現,不用我們去實現介面中的所有方法。

2、MockUp中mock的方法一定要與對應介面中方法簽名一致,否則會報錯java.lang.IllegalArgumentException: Matching real methods not found for the following mocks。

3、MockUp中的方法一定要加@Mock註解,否則會被jmockit忽略,不能達到mock的目的。


我使用的jmockit版本如下:

<dependency>
	<groupId>org.jmockit</groupId>
	<artifactId>jmockit</artifactId>
	<version>1.22</version>
</dependency>


相關文章