2016-09-06 58 views
1

私は、PowerMockitoを使用してIOExceptionをスローする静的なクラスをモックしようとしています。私は私のパッケージでJUnit 4.12とPowerMockMockito 1.6.3を使用しています。しかし、私はクラス定義の上に置く必要がある "@RunWith(PowerMockRunner.class)"アノテーションのために "initializationError"を取得します。これは、テストクラスが空であっても発生します。ここで 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) 

私の試みはPowerMockitoが1.6に更新された後、同様の問題が解決されたthis 1、のようないくつかの古いSOの質問に私をリードしてきました.1。残念ながらそれはあまり役に立ちませんでした。

私はPowerMockitoを初めて使用しているので、どのガイドでもあまりにも明白な内容が記載されていない可能性があります。どのように私はこれを解決することができるかに関する任意のアイデア?前もって感謝します。

+1

私の答えではカットされず、ここで実際の答えが得られない(何が起こるか)... https://groups.google.com/forum /#!forum/powermock - PM開発者が読む場所です。 – GhostCat

+0

あなたはあなたのテストクラスをアップデートできます – kuhajeyan

答えて

2

すべてがあなたのコードであれば、それほど微妙な解決策はありません: PowerMockとこの種の問題を完全に避けてください。その代わりに、の静的なは、良いOO設計の異常です。これは、クラスの直接的、ハードな結合につながります。

テスト可能なように大きなPowermockハンマーが必要なテスト困難なコードを書くのではなく、静的なコードを避けるコードを用意してください。したがって、Powermockを必要とせずにテストすることができます。

短いストーリー:テスト可能なコードを書くことについて学びます(例:これらの[ビデオ] [1]を聞くなど)。そして、Powermock部屋へのドアを閉じさせてください。そして、そのとき静的あなたは所有していない外部コードにも存在します。 まだにラッパーを置き、直接の依存関係を避けることができます。

編集:もちろん、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. は、あなたのClientクラス
  2. に最小限のオーバーヘッドで、既存の静的メソッドTheStaticThingFunctionalityの
  3. パス嘲笑のインスタンスを使用し続けます

今では、を完全ににすることができます。もっと重要なのは、Apachaceのコモンズが提供する実装から自分自身を切り離すための第一歩をすでに踏んでしまったことです。あなたが今StashThingImplを必要に応じて他のものと交換することができます。

+0

詳細を教えてください。私がやろうとしているのは、たくさんのファイルを1つのファイルにマージすることです。私はこれを行うためにApache Commons FileUtilsライブラリを使用しています。使用する読み取り/書き込み操作ではすべてIOExceptionが発生する可能性があります。例外が発生した場合は、すべてを元の状態に戻す必要があります。これは、半完成の結合ファイルを消去することを意味します。私は例外を処理する以外に多くの選択肢がないように見えます。 –

+0

最新情報を見る! – GhostCat