Easymock 拡張機能を備えた Powermock 1.4.9 を使用しています。
以下は、私がテストしたい方法です
Public class SomeClass {
public String methodToTest(String id) throws Exception {
try {
ClassA ojbectA = MyFactory.staticMethod();
String str = helperMethod(id);
ojbectA.methodA(str);
return objectA.methodB(str);
}
catch (Exception e) {
throw e;
}
}
}
以下は、上記のメソッドをテストするために作成したテストクラスとテストです。Static メソッドと Private メソッドの呼び出しがあるため、PowerMock と EasyMock の両方を使用します。
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.easymock.EasyMock.isA;
import static org.powermock.api.easymock.PowerMock.mockStatic;
@RunWith(PowerMockRunner.class)
@PrepareForTest{{SomeClass.class,MyFactory.class, ClassA.class}}
public class TestClass {
@Test
public void testMethod1() {
try {
ClassA mockA = PowerMock.createMock(ClassA.class);
mockStatic(MyFactory.class);
SomeClass someObj = PowerMock.createPartialMock(SomeClass.class,"helperMethod");
String mockLog = "This is sample";
String mockId = "mockId";
String woMockId = "WO_mockId";
//Mock all static methods
EasyMock.expect(MyFactory.staticMethod()).andReturn(mockA);
//Partial mocking
PowerMock.expectPrivate(someObj,"helperMethod",mockId).andReturn(woMockId);
//Mock methodA(String) method
mockA.methodA(EasyMock.isA(String.class));
PowerMock.expectLastCall().times(0, 1);
//When methodB(String) is called, intercept it and return a standard value.
EasyMock.expect(mockA.methodB(isA(String.class))).andReturn(mockLog);
EasyMock.replay(mockA);
EasyMock.replay(someObj);
PowerMock.replay(MyFactory.class);
String obtainedResult = someObj.getWorkorderLogByWoId(mockId);
assertEquals(obtainedResult,mockLog);
EasyMock.verify(mockA);
EasyMock.verify(someObj);
PowerMock.verify(MyFactory.class);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
これは、Intellij IDEA と Eclipse の両方で例外なく正常に動作します。しかし、ANT を使用してコマンド ラインでこのテストを実行すると、次の例外が発生します。
java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521)
at org.easymock.EasyMock.expect(EasyMock.java:499)
at com.xyz.ems.server.services.workorder.TestClass.testMethod1(TestClass.java:<some_line_number>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:518)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1052)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:906)
文字列を差し替えずにオリジナルコードの要望がありました。以下はコードです。
import com.xyz.ems.common.UnitTestCase;
import com.xyz.ems.server.services.logmessage.LogMessageManager;
import com.xyz.ems.server.services.workorder.database.WorkOrderManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.createPartialMock;
import static org.powermock.api.easymock.PowerMock.expectLastCall;
import static org.powermock.api.easymock.PowerMock.expectPrivate;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.powermock.api.easymock.PowerMock.replay;
import static org.powermock.api.easymock.PowerMock.verify;
@RunWith(PowerMockRunner.class)
@PrepareForTest({WorkOrderManager.class,WorkOrderFactory.class, LogMessageManager.class})
public class WorkOrderManagerPM_JTest extends UnitTestCase {
public WorkOrderManagerPM_JTest(String name) {
super(name);
}
@Before
public void firstMethod() {
assertTrue(true);
}
@After
public void lastMethod() {
assertTrue(true);
}
@Test
public void testGetWoLogByObjectId() {
try {
LogMessageManager logMsgMgrMock = createMock(LogMessageManager.class);
mockStatic(WorkOrderFactory.class);
WorkOrderManager wMgr = createPartialMock(WorkOrderManager.class,"buildWorkOrderIdString");
String mockLog = "This is sample";
String mockId = "mockId";
String woMockId = "WO_mockId";
//Mock all static methods
expect(WorkOrderFactory.getLogMessageManager()).andReturn(logMsgMgrMock);
//Partial mocking
expectPrivate(wMgr,"buildWorkOrderIdString",mockId).andReturn(woMockId);
//Mock openLogMessageDoc() method
logMsgMgrMock.openLogMessageDoc(isA(String.class));
expectLastCall().times(0, 1);
//When getAllLogMessageAsString() is called, intercept it and return a standard value.
expect(logMsgMgrMock.getAllLogMessagesAsString(isA(String.class))).andReturn(mockLog);
replay(logMsgMgrMock);
replay(wMgr);
replay(WorkOrderFactory.class);
String obtainedResult = wMgr.getWorkorderLogByWoId(mockId);
assertEquals("getWorkorderLogByWoId() general case passed",obtainedResult,mockLog);
verify(logMsgMgrMock);
verify(wMgr);
verify(WorkOrderFactory.class);
}
catch (Exception e) {
e.printStackTrace();
fail("Failed to test getWorkorderLogById()");
}
}
そして、テスト中の元のメソッド...
public class WorkOrderManager {
public String getWorkorderLogByWoId(String woId) throws WorkOrderServiceEMSException {
try {
LogMessageManager logMsgMgr = WorkOrderFactory.getLogMessageManager();
String workOrderLogId = buildWorkOrderIdString(woId);
logMsgMgr.openLogMessageDoc(workOrderLogId);
return logMsgMgr.getAllLogMessagesAsString(workOrderLogId);
}
catch (Exception e) {
String msg = "Failed to get Work Order Log for workorder Id : " + woId;
throw new WorkOrderServiceEMSException(msg, WorkOrderServiceEMSError.WO_GET_WOLOG_BY_OBJECTID.newInstanceWithFormatArgs(woId), e);
}
}
}