在Junit4(PowerMock)中实现Mocking时的依赖关系

时间:2017-07-11 11:04:57

标签: java unit-testing junit jar powermock

以下是我的JUnit测试用例:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Date;
import java.util.HashMap;
import static org.easymock.EasyMock.expect;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.annotation.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.powermock.api.easymock.PowerMock.replayAll;
import static org.powermock.api.easymock.PowerMock.verifyAll;

@RunWith(PowerMockRunner.class)
@PrepareForTest({CollectionUtil.class, DateUtil.class})
public class JTestReportUtil
{
    @Mock
    private CollectionUtil m_collectionUtil;
    private DateUtil m_dateUtil;

    private ReportUtil m_reportUtil;

    @Before
    public void setUp()
    {
        m_reportUtil = new ReportUtil();
    }

    @Test
    public void testRemoveHashedSettings() throws Exception 
    {
        try
        {
            HashMap<String, String> w_abc = new HashMap<String, String>();
            w_abc.put("abc", "89");    

            //check for null  
            assertNull(ReportUtil.removeHashedSettings(null, null, null));

            //check for actual
                    mockStatic(CollectionUtil.class);
           expect(m_collectionUtil.createHashMap("abc:89", ":")).andReturn(w_abc);
           replayAll();
           String w_result = m_reportUtil.removeHashedSettings("1", "abc:89", ":");
           verifyAll();
           assertEquals("abc:89:",w_result);

        }
        catch (Exception e)
        {
            fail(e.getMessage());
        }
    }

我在构建路径中包含了以下jars

  1. powermock-EasyMock的-1.4.10-full.jar
  2. powermock模块-junit4-1.6.6.jar
  3. EasyMock的-3.4.jar
  4. powermock核-1.6.6.jar
  5. 依赖关系中仍然出现以下错误:

    java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Enhancer
        at org.powermock.api.extension.proxyframework.ProxyFrameworkImpl.isProxy(ProxyFrameworkImpl.java:29)
        at org.powermock.reflect.internal.WhiteboxImpl.getUnmockedType(WhiteboxImpl.java:1783)
        at org.powermock.reflect.internal.WhiteboxImpl.getType(WhiteboxImpl.java:2237)
        at org.powermock.reflect.internal.WhiteboxImpl.setInternalState(WhiteboxImpl.java:327)
        at org.powermock.reflect.proxyframework.RegisterProxyFramework.registerProxyFramework(RegisterProxyFramework.java:18)
        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.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:2014)
        at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:885)
        at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859)
        at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.registerProxyframework(AbstractTestSuiteChunkerImpl.java:154)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.getPowerMockTestListenersLoadedByASpecificClassLoader(AbstractTestSuiteChunkerImpl.java:107)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:174)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:217)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
        at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
        at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:26)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
        at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
        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)
    Caused by: java.lang.ClassNotFoundException: net.sf.cglib.proxy.Enhancer
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:143)
        at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:65)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        ... 38 more
    

    为什么junit 4中的模拟需要如此多的依赖?我不能只用2个或3个罐子吗?

    在构建路径中添加cglib后会出现另一个错误:

    java.lang.ExceptionInInitializerError
        at org.powermock.api.extension.proxyframework.ProxyFrameworkImpl.isProxy(ProxyFrameworkImpl.java:29)
        at org.powermock.reflect.internal.WhiteboxImpl.getUnmockedType(WhiteboxImpl.java:1783)
        at org.powermock.reflect.internal.WhiteboxImpl.getType(WhiteboxImpl.java:2237)
        at org.powermock.reflect.internal.WhiteboxImpl.setInternalState(WhiteboxImpl.java:327)
        at org.powermock.reflect.proxyframework.RegisterProxyFramework.registerProxyFramework(RegisterProxyFramework.java:18)
        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.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:2014)
        at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:885)
        at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859)
        at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.registerProxyframework(AbstractTestSuiteChunkerImpl.java:154)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.getPowerMockTestListenersLoadedByASpecificClassLoader(AbstractTestSuiteChunkerImpl.java:107)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:174)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
        at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:217)
        at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
        at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
        at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:26)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
        at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
        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)
    Caused by: java.lang.IllegalStateException: Unable to load cache item
        at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:79)
        at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
        at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116)
        at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291)
        at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
        at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
        at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
        at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
        ... 38 more
    Caused by: java.lang.IncompatibleClassChangeError: class net.sf.cglib.core.DebuggingClassWriter has interface org.objectweb.asm.ClassVisitor as super class
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:143)
        at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:65)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at net.sf.cglib.core.DefaultGeneratorStrategy.getClassVisitor(DefaultGeneratorStrategy.java:30)
        at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:24)
        at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:329)
        at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:93)
        at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91)
        at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
        ... 45 more
    

1 个答案:

答案 0 :(得分:2)

您缺少 cglib 库。

参见this讨论;他们解释了cglib是如何从PowerMock演变成自己的库的。

将所有内容放在一起的最简单方法 - 阅读并遵循downloads文档。你会在那里找到各种ZIP文件。

当您打算使用PowerMock + easymock + JUnit时,只需从那里下载powermock-easymock-junit-1.7.0.zip即可。解压缩ZIP文件,然后将所有 JAR包含到类路径中。