模拟时junit出错

我是Junit的新手,下面是我正在运行的junit代码。

package com.de.base.util.general; import static org.junit.Assert.*; import static org.mockito.Mockito.when; import java.util.HashMap; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.powermock.api.mockito.PowerMockito; @RunWith(MockitoJUnitRunner.class) public class JReportUtilTest { @InjectMocks ReportUtil w_res = new ReportUtil(); @Mock CollectionUtil w_util; @Test public void test_removeHashedSettings() throws Exception { HashMap w_abc = new HashMap(); w_abc.put("abc","89"); //CollectionUtil mock = org.mockito.Mockito.mock(CollectionUtil.class); //PowerMockito.mockStatic(CollectionUtil.class,w_abc); when(w_util.createHashMap("abc:89", ":")).thenReturn(w_abc); assertEquals("abc:89:",ReportUtil.removeHashedSettings("1", "abc:89", ":")); } } 

这是我的api removedHashedSettingsin ReportUtil

 public static String removeHashedSettings(String key, String a_settings, String deilimiter) throws Exception { if (!(key != null && key.trim().length() > 0)) return a_settings; if (!(a_settings != null && a_settings.trim().length() > 0)) return a_settings; HashMap hSettings = CollectionUtil.createHashMap(a_settings, deilimiter); hSettings.remove(key); return getSettingFromHash(hSettings, deilimiter); } 

下面是CollectionUtil中createHashMap的代码,我必须进行模拟。

 public static HashMap createHashMap(String a_NameValStr, String a_Delim)// throws Exception { HashMap w_KeyVal = new HashMap(); if (LOGGER.isInfoEnabled()) LOGGER.info("CollectionUtil:createHashMap:Hashing string: "+ a_NameValStr ); if(a_NameValStr == null) return w_KeyVal; StringTokenizer w_StrTkn = new StringTokenizer(a_NameValStr, a_Delim); if( w_StrTkn.countTokens() == 0 || (w_StrTkn.countTokens()%2) != 0 ) { LOGGER.warn("CollectionUtil:createHashMap:Invalid number of tokens to hash: "+ a_NameValStr+":"+w_StrTkn.countTokens() ); return w_KeyVal; } while (w_StrTkn.hasMoreTokens()) w_KeyVal.put( w_StrTkn.nextToken(), w_StrTkn.nextToken()); System.out.println(w_KeyVal); return w_KeyVal; } 

这是我在运行junit测试用例时遇到的错误。

  org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles); Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods *cannot* be stubbed/verified. Mocking methods declared on non-public parent classes is not supported. 2. inside when() you don't call method on mock but on some other object. at com.de.base.util.general.JReportUtilTest.test_removeHashedSettings(JReportUtilTest.java:32) 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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

我正在使用mockito -all-1.10.19.jar,powermock-api-mockito-1.6.6.jar,powermock-core-1.6.6.jar,powermock-module-junit4-1.6.6.jar任何人都可以帮助我解决这个问题?

这是我的工作代码:

 import static org.junit.Assert.assertEquals; import java.util.HashMap; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(CollectionUtil.class) public class TestHarnesTest { @InjectMocks TestHarnes w_res = new TestHarnes(); @Before public void before() { PowerMockito.mockStatic(CollectionUtil.class); } @Test public void test_removeHashedSettings() throws Exception { HashMap w_abc = new HashMap(); w_abc.put("abc", "89"); // CollectionUtil mock = org.mockito.Mockito.mock(CollectionUtil.class); // PowerMockito.mockStatic(CollectionUtil.class,w_abc); PowerMockito.when(CollectionUtil.createHashMap(Mockito.eq("abc:89"), Mockito.eq(":"))).thenReturn(w_abc); assertEquals("abc:89:", TestHarnes.removeHashedSettings("1", "abc:89", ":")); } } 

和TestHarnes类

 public class TestHarnes { public static String removeHashedSettings(final String key, final String a_settings, final String deilimiter) throws Exception { if (!(key != null && key.trim().length() > 0)) { return a_settings; } if (!(a_settings != null && a_settings.trim().length() > 0)) { return a_settings; } HashMap hSettings = CollectionUtil.createHashMap(a_settings, deilimiter); hSettings.remove(key); return getSettingFromHash(hSettings, deilimiter); } private static String getSettingFromHash(final HashMap hSettings, final String deilimiter) { return ""; } } 

您不使用PowerMock运行器:

 @RunWith(PowerMockRunner.class) 

Mockito不能模拟静态方法,但PowerMock可以。

你应该用静态方法模拟类:

 PowerMockito.mockStatic(CollectionUtil.class); 

无论如何,更好的设计是用实例方法替换静态方法。
静态方法不是自然可测试的,并且强制创建复杂且不可读的变通方法。
例如,查看测试简单类所需的依赖项组合的复杂性。

您应该将静态方法使用保持为不执行域的核心逻辑且不需要模拟的帮助程序

当方法执行域的核心逻辑时,就像createHashMap() static method ,您可能需要模拟它以在测试期间不在依赖类之间创建副作用。
正如您所注意到的那样:模拟静态方法实际上非常笨拙,因为静态方法实际上并不是为了覆盖而设计的。

此外,对于域的核心逻辑,您应该能够利用OOP(inheritance,多态,设计模式等),如何使用静态方法实现它? –

对于遗留代码,我们不能真正改变,它是可以接受的,否则,不是没有,你应该重构你的代码。