2016-09-06 3 views
1

Я пытаюсь использовать PowerMockito, чтобы издеваться над статическим классом, бросающим исключение IOException. Я использую JUnit 4.12 и PowerMockMockito 1.6.3 в своем пакете. Тем не менее, я получаю «initializationError» из-за аннотации @RunWith (PowerMockRunner.class), которую мне нужно поставить выше определения класса. Это происходит, даже если тестовый класс пуст.Ошибка инициализации PowerMockRunner

Вот трассировки стека ошибки:

org.powermock.reflect.exceptions.FieldNotFoundException: Field 'fTestClass' was not found in class org.junit.internal.runners.MethodValidator. 
at org.powermock.reflect.internal.WhiteboxImpl.getInternalState(WhiteboxImpl.java:581) 
at org.powermock.reflect.Whitebox.getInternalState(Whitebox.java:308) 
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validateTestMethods(PowerMockJUnit4MethodValidator.java:97) 
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validateInstanceMethods(PowerMockJUnit4MethodValidator.java:67) 
at org.junit.internal.runners.MethodValidator.validateMethodsForDefaultRunner(MethodValidator.java:51) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.<init>(PowerMockJUnit44RunnerDelegateImpl.java:70) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:156) 
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40) 
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244) 
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:61) 
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32) 
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
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.JUnit4TestReference.<init>(JUnit4TestReference.java:33) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

Мои попытки решить эту проблему привела меня к несколько более старых SO вопросов как this один, где аналогичная проблема была решена после того, как PowerMockito была обновлена ​​до 1.6 0,1. К сожалению, это было не очень полезно.

Я новичок в PowerMockito, поэтому я могу пропустить что-то слишком очевидное, чтобы быть упомянутым в любых руководствах. Любые идеи о том, как я могу это решить? Заранее спасибо.

+1

В случае, если мой ответ не сократит его, и вы не получите никакого «реального» ответа здесь (что происходит довольно часто) ... вы можете попробовать здесь: https://groups.google.com/forum/#! forum/powermock - вот где читатели PM читают. – GhostCat

+0

Можете ли вы обновить свои тестовые классы – kuhajeyan

ответ

2

Если все это ваш код, то не столь тонкое решение будет: избежать PowerMock, и такого рода проблемы полностью. Вместо этого согласитесь, что статический - ненормальность в хороших конструкциях OO - поскольку это приводит к прямой, жесткой связи ваших классов.

Поэтому вместо того, чтобы писать жесткий код, требующий большого молотка Powermock, чтобы его можно было проверить: придумать код, который позволяет избежать статичности; и что таким образом можно протестировать без необходимости в Powermock.

Краткая история: узнайте о написании проверяемого кода (например, прослушав эти [видео] [1]). И пусть дверь в комнату Powermock закрыта. И когда этот статический thingy живет во внешнем коде, который у вас нет; вы можете еще положить обертку вокруг него и избежать прямой зависимости.

Edit: Конечно, это громоздко работать вокруг такую ​​центральную вещь, как Apache Commons, но все же, вы можете всегда сделать что-то вроде:

class TheStaticThing { 
    public static Whatever doSomething(Somethin els) throws StupidException { ... 

вы можете пересылать и «интерфейс» это :

interface TheStaticThingFunctionality { 
    public static Whatever doSomething(Somethin els) throws StupidException; 

Тогда у вас есть простой

class TheStaticThingImpl implements TheStaticThingFunctionality { 
    @Override 
    public Whatever doSomething(Somethin els) throws StupidException { 
    return TheStaticThing.doSomething(els); 
    } 

И теперь в классе клиента:

class Client { 
    private final TheStaticThingFunctionality func; 
    Client() { this(new TheStaticThingImpl()); } 
    Client(TheStaticThingFunctionality func) { this.func = func; } 

Этот код позволяет:

  1. продолжать использовать существующие статические методы с минимальными затратами
  2. прохода издевались экземплярами TheStaticThingFunctionality в класс Client

И теперь вы можете полностью контроль, когда вы не хотите летать; и что еще более важно: вы уже сделали первый шаг к развязыванию себя от реализации, предоставленной Apachace commons, так как теперь вы можете бесплатно обменять TheStaticThingImpl с чем-то другим, если вы видите необходимость в этом!

+0

Не могли бы вы подробнее рассказать? То, что я пытаюсь сделать, - объединить кучу файлов в один файл. Я использую библиотеку Apache Commons FileUtils для этого, и операции чтения/записи, которые я использую, могут вызвать IOException. Если возникает исключение, мне нужно вернуть все в исходное состояние, что означает стирание полузаполненного объединенного файла. Похоже, у меня нет выбора, кроме как справиться с исключением. –

+0

Просмотреть мои обновления! – GhostCat

Смежные вопросы