5

我有一个测试特定控制器的类,它工作正常

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:config/test-applicationContext-config.xml")
@TestExecutionListeners({ 
    WebContextTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })
public class TestAdminController {  
     //.....
}

我在那里使用来自mockito.org的 Google 的 Mockito 库来模拟我的底层 bean。

现在我的问题如下:我有一些类也需要模拟,但它们有final方法,谷歌的模拟似乎没有解决这个问题。我的一位同事建议使用 powermock.org 的Powermock。但它需要用注释来注释测试器类@RunWith(PowerMockRunner.class)。如果我使用它,我必须删除注释@RunWith(SpringJUnit4ClassRunner.class),这会给我带来问题,因为不会创建 Spring 测试上下文。我怎样才能避免这种情况?

建议后我已配置为使用PowerMockRule而不是@RunWith注释

我的项目maven依赖如下

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-mockito-release-full</artifactId>
    <version>1.5</version>
    <type>pom</type>
</dependency> 
<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4-rule</artifactId>
        <version>1.5</version>
        <scope>test</scope>
</dependency>
<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-classloading-xstream</artifactId>
        <version>1.5</version>
        <scope>test</scope>
</dependency>

现在我的课看起来像这样(另一个控制器测试)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:config/test-applicationContext-config.xml")
@TestExecutionListeners({ 
    WebContextTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })
@PrepareForTest(ADSynchronizationImpl.class)
public class ThirdPartyLoginControllerTest {
    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Autowired
    private ThirdPartyLoginController thirtPartyLoginController;

    @Autowired
    private MockFactoryForControllers mockFactory;

    @Test
    public void testLoginActiveDirectory(){

    }
}

但是在运行我的测试之后,我得到了以下异常跟踪

com.thoughtworks.xstream.converters.ConversionException:javassist.NotFoundException:com.somecompany.analytics.manager.db.api.MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415:javassist.NotFoundException:com.somecompany.analytics.manager.db.api。 MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415 ---- 调试信息 ---- 消息:javassist.NotFoundException: com.somecompany.analytics.manager.db.api.MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415 原因异常:java.lang。 RuntimeException 原因消息:javassist.NotFoundException:com.somecompany.analytics.manager.db.api.MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415 类:com.somecompany.ui.controllers.ThirdPartyLoginController 所需类型:com.somecompany.ui.controllers .ThirdPartyLoginController 转换器类型:com.thoughtworks。xstream.converters.reflection.ReflectionConverter 路径:/org.powermock.modules.junit4.rule.PowerMockStatement$1/outer-class/fNext/fTarget/thirtPartyLoginController/mlDao 行号:14 类1 :com.somecompany.ui.controllers.ThirdPartyLoginControllerTest 类2 :org.junit.internal.runners.statements.InvokeMethod 类[3]
:org.powermock.modules.junit4.rule.PowerMockStatement 类[4]
:org.powermock。 modules.junit4.rule.PowerMockStatement$1 版本
: null ------------------- 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java: 79) 在 com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 在 com.thoughtworks.xstream.converters.reflection .AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarstract.java(Abs :234) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 在 com。thinkworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField( AbstractReflectionConverter.java:355) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 在 com .thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 在 com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 在 com.thoughtworks.xstream.core。TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java: 306) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 在 com.thoughtworks.xstream.core .AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter。unmarshallField(AbstractReflectionConverter.java:355) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:23)在 com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 在 com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother (TreeUnmarshaller.java:66) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) 在 com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) 在 com.thoughtworks。 xstream.core。AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1052) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1036) at com.thoughtworks.xstream .XStream.fromXML(XStream.java:912) 在 com.thoughtworks.xstream.XStream.fromXML(XStream.java:903) 在 org.powermock.classloading.DeepCloner.clone(DeepCloner.java:54) 在 org.powermock。 classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:89) at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) 在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 在 org.springframework.test。 context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java: 53) 在 org.springframework.test.context.junit4.statements 的 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)。RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:309)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) 在 org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 在 org.eclipse.jdt .internal.junit.runner.TestExecution.run(TestExecution.java:38) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 在 org.eclipse.jdt.internal.junit .runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 引起:java.lang.RuntimeException:javassist.NotFoundException:com.somecompany.idm.analytics.manager.db。 api.MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415 at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:199) at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:149) at org. powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at com.thoughtworks.xstream.core.util.ClassLoaderReference.loadClass(ClassLoaderReference.java: 31) 在 com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:49) 在 com.thoughtworks。xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java: 30) 在 com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.ClassAliasingMapper .realClass(ClassAliasingMapper.java:79) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com。 com.thoughtworks.xstream.mapper.MapperWrapper 上的 thinkworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)。realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks .xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java :30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper。 MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream。mapper.MapperWrapper.realClass(MapperWrapper.java:30) 在 com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:45) 在 com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.determineType(AbstractReflectionConverter.java:第 458 章.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) ... 57 更多原因:javassist.NotFoundException: com.somecompany.analytics.manager.db.api.MlDao$$EnhancerByMockitoWithCGLIB$$b86d7415 at javassist.ClassPool.get (ClassPool.java:450) 在 org.powermock.core。classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:192) ... 87 更多

4

3 回答 3

6

看看这篇文章,它解释了如何使用 PowerMock 和SpringJUnit4ClassRunner. 基本上,你只需要使用一个特殊的PowerMockRule规则

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:config/test-applicationContext-config.xml")
@TestExecutionListeners({ 
    WebContextTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })
public class SpringExampleTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

}

编辑:其他人似乎和你有同样的问题@PowerMockRule改用 PowerMockAgent可以解决您的问题。另请参阅SO 上的这个答案

于 2013-03-05T13:18:01.093 回答
6

您也可以尝试使用注释您的测试类

@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)

请参见此处的示例。

于 2016-08-23T09:47:52.397 回答
3

您可以使用 JMockit 而不是 Powermock。它可以做 Powermock 可以做的所有事情,而且它不需要 @RunWith 子句,因此它不会干扰您的 Spring 测试运行器。我发现 PowerMockRule 引入的问题多于它解决的问题......

于 2013-09-25T13:03:34.543 回答