我正在尝试测试一个实用程序类与一堆静态方法。我正在为调用另外两个静态方法的方法编写测试。在第一个静态方法调用上,mock似乎有效,但它忽略了第二个期望并调用真正的方法。任何想法?我试着在第二次期望之前提供第二个PowerMock.spy(Utils.class),但没有运气。你知道怎么解决这个问题吗?
下面是示例代码。
package com.personal.test;
import java.io.IOException;
public class Utils {
public static String testUtilOne() {
System.out.println("Static method one");
return "methodone";
}
public static void testUtilsTwo(String s1, String s2, String s3) throws IOException {
throw new IOException("Throw an exception");
}
public static void testUtilsThree() throws TestException {
try {
String s = testUtilOne();
testUtilsTwo("s1", s, "s3");
} catch (IOException ex) {
throw new TestException("there was an exception", ex);
}
}
public static class TestException extends Exception {
public TestException() {
super();
}
public TestException(String message, Exception cause) {
super(message, cause);
}
}
}
package com.personal.test;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.personal.test.Utils.TestException;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Utils.class})
public class UtilsTest {
@Test
public void testMethodThreeWrapsException() throws Exception {
PowerMockito.spy(Utils.class);
PowerMockito.when(Utils.class, "testUtilOne").thenReturn("This is coming from test");
PowerMockito.spy(Utils.class);
PowerMockito.when(Utils.class, "testUtilsTwo", Mockito.anyString(), Mockito.anyString(), Mockito.anyString()).thenThrow(new IOException("Exception from test"));
try {
Utils.testUtilsThree();
} catch (TestException ex) {
Assert.assertTrue(ex.getCause() instanceof IOException);
Assert.assertEquals("Exception from test", ex.getMessage());
}
}
}
如果有人感兴趣的话,花了一整天的时间,我终于解决了这个问题。我首先staticmock我的Utils类(这将模拟所有的静态方法),然后要求mock调用真正的方法为teststutilsthree调用。修改如下:
package com.personal.test;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.personal.test.Utils.TestException;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Utils.class})
public class UtilsTest {
@Test
public void testMethodThreeWrapsException() throws Exception {
PowerMockito.mockStatic(Utils.class);
PowerMockito.when(Utils.class, "testUtilOne").thenReturn("This is coming from test");
PowerMockito.when(Utils.class, "testUtilsTwo", Mockito.anyString(), Mockito.anyString(), Mockito.anyString()).thenThrow(new IOException("Exception from test"));
PowerMockito.doCallRealMethod().when(Utils.class, "testUtilsThree");
try {
Utils.testUtilsThree();
} catch (TestException ex) {
Assert.assertTrue(ex.getCause() instanceof IOException);
Assert.assertEquals("Exception from test", ex.getMessage());
}
}
}