Тестирование контроллеров Spring с помощью Powermock

У меня есть класс, который тестирует конкретный контроллер, и он отлично работает

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

Я использовал библиотеку Google Mockito из mockito.org, чтобы издеваться над моими базовыми компонентами.

Теперь мой вопрос заключается в следующем: у меня есть несколько классов, которые также нужно имитировать, но у них есть final методы, и mockito от Google, похоже, не решает эту проблему. Один из моих коллег предложил использовать Powermock с сайта powermock.org. Но для этого требуется аннотировать класс тестера аннотацией @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(){

    }
}

Но после запуска моего теста я получаю следующую трассировку исключения

Взгляните на эту статью который объясняет, как использовать PowerMock и

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:config/test-applicationContext-config.xml")
@TestExecutionListeners({ 
    WebContextTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })
public class TestAdminController {  
     //.....
}
. По сути, вам просто нужно использовать специальное final правило:


person Arsen Alexanyan    schedule 05.03.2013    source источник


Ответы (3)


Изменить: кажется, что у у других людей была та же проблема, что и вы относительно @PowerMockRule. Использование PowerMockAgent вместо этого может решить вашу проблему. См. также этот ответ на SO.

@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();

}

Вы также можете попытаться аннотировать свой тестовый класс с помощью

person Bastien Jansen    schedule 05.03.2013
comment
На самом деле в статье говорится, что XStream более надежен, чем Objenesis, и ошибки, о которых они упоминают, появляются с Objenesis. Я использовал XStream в других проектах (не с PowerMock), и у меня никогда не было проблем. Сталкивались ли вы с такими ошибками? - person Arsen Alexanyan; 05.03.2013
comment
Спасибо за ваши предложения, после использования с Spring у меня возникла ошибка. Я отредактировал пост, чтобы быть более понятным - person Bastien Jansen; 05.03.2013
comment
Не могли бы вы посмотреть, есть ли у вас несколько версий Mockito в пути к классам? Такие ошибки часто возникают, когда два разных загрузчика классов загружают две разные версии одной и той же зависимости. _1_ может помочь вам разобраться в этом. - person Arsen Alexanyan; 06.03.2013
comment
Да, кажется, у меня было несколько версий пути к классам. Но после исправления у меня появилась другая ошибка. Я изменил трассировку исключения - person Bastien Jansen; 06.03.2013
comment
Я отредактировал свой ответ, возможно, _1_ решит вашу проблему. В любом случае, кажется сложным использовать PowerMock в интеграционном тесте Spring :) - person Arsen Alexanyan; 06.03.2013
comment
Спасибо, ваш опубликованный ТАК ответ был полезен! - person Bastien Jansen; 06.03.2013
comment
Кроме того, добавьте _1_ перед частью делегата - person Arsen Alexanyan; 06.03.2013

См. пример здесь.

@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)

Вы можете использовать JMockit вместо Powermock. Он может делать все, что может делать Powermock, и ему не нужно предложение @RunWith, поэтому он не мешает вашему запуску тестов Spring. Я обнаружил, что PowerMockRule создает больше проблем, чем решает...

person gce    schedule 23.08.2016
comment
Ссылка на пример мертва - person KumarAnkit; 28.12.2018
comment
@jpmottin попробуйте заглянуть в предыдущие версии, я смог найдите этот файл для тега 1.6.0. - person jpmottin; 13.10.2020
comment
Спасибо @gce ???? не могли бы вы обновить предоставленную ссылку в исходном сообщении? - person gce; 15.10.2020
comment
Спасибо за предложение, я попробую это. - person jpmottin; 15.10.2020

Я пробовал это, но кажется, что библиотека X-Stream под powermock подвержена ошибкам, о чем также говорится в вашей опубликованной статье.

person Justin Rowe    schedule 25.09.2013
comment
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-cla ss/fNext/fTarget/thirtPartyLoginController/mlDao номер строки : 14 class1 : com.somecompany. ui.controllers.ThirdPartyLoginControllerTest class2 : класс org.junit.internal.runners.statements.InvokeMethod [3]
: org.powermock.modules.junit4.rule.PowerMockStatement class[4]
: org.powermock.modules.junit4.rule.PowerMockStatement$1 version
: 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) в с om.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) в com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:355) 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 ) по адресу com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(A bstractReflectionConverter.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) по адресу 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.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) на com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) на com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) на com.thoughtworks.xstream. XStream.unmarshal(XStream.java:1052) в com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1036) в 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) в org.powermock. classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) в 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) в org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) в org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) в org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) в org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) в org.junit.runners.ParentRunner.access$000(ParentRunner.java: 53) в org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) в org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) в org.springframework.test. context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) в 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 в org.powermock.core .classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:199) в org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:149) в org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) ) в java.lang.ClassLoader.loadClass(ClassLoader.java:356) в 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 .карта er.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.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.ArrayMapper.realClass(ArrayMapper.java: 74) на com.thoughtworks.xstream.mapper.Mappe rWrapper.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) на com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:294) на com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) на com.thoughtworks.xstream.core .TreeUnmarshaller.convert(TreeUnmarshaller.java:72) ... еще 57. .java:450) на org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:192) ... еще 87 - person Arsen Alexanyan; 30.10.2013