PowerMockito.whenNew()の使用がモックされず、元のメソッドが呼び出されます


99

以下のようなコードがあります:

Class A {
  public boolean myMethod(someargs) {
    MyQueryClass query = new MyQueryClass();
    Long id = query.getNextId();
    // some more code
  }
}
Class MyQueryClass     {
  ....
  public Long getNextId() {
    //lot of DB code, execute some DB query
    return id;
  }
}

今、私はのテストを書いていA.myMethod(someargs)ます。実際のメソッドをスキップしてquery.getNextId()、代わりにスタブ値を返したいのですが。基本的に、私はあざけりたいですMyQueryClass

だから私のテストケースでは、私は使用しました:

MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);

boolean b = A.getInstance().myMethod(args);

//asserts

私はテストクラスの初めに使用@RunWith(PowerMockRunner.class)@PrepareForTest({MyQueryClass.class})ました。

しかし、テストをデバッグするとき、それはまだクラスの実際のメソッドgetNextId()を呼び出していMyQueryClassます。

ここで何が欠けていますか?MockitoとPowerMockitoが初めてなので、誰でも手伝ってくれますか。

回答:


219

構築されて@PrepareForTestいるクラスの代わりに、コンストラクターが呼び出されたクラスをアノテーションに配置する必要があります新しいオブジェクトのモック構築を参照してください。

あなたの場合:

@PrepareForTest(MyQueryClass.class)

@PrepareForTest(A.class)

より一般的な:

@PrepareForTest(NewInstanceClass.class)

@PrepareForTest(ClassThatCreatesTheNewInstance.class)


1
どうもありがとう。現在のクラスEg Aを@PrepareForTestに含めた後、現在は機能しています。
user3942446 2014

2
私もこれのためにしばらく過ごします。@TrueDubに感謝します。参照が古くなっているため。更新するだけです。github.com/jayway/powermock/wiki/MockConstructorそれは言う:テストケースのクラスレベルで@PrepareForTest(ClassThatCreatesTheNewInstance.class)アノテーションを使用します。
Victor Choy

4
私は同じ問題を抱えていますが、この解決策は私にとってはうまくいきません
dexter '13

3
コードカバレッジにeclemmaを使用している場合、このソリューションは機能しません。テスト対象のクラスを@PrepareForTestに追加すると、そのクラスのカバレッジが0%になります
ACV

2
ソリューションは機能します-テストは正しく実行されます。明らかに、eclemmaはPowerMockitoを処理するために装備されていません。コードカバレッジはこの質問の一部ではありません。
TrueDub 2017年

3

@TrueDubが受け入れた返信で述べたように、コンストラクタが呼び出されるクラスをに追加する必要があります@PrepareForTest

ただし、これを行うと、eclemmaとSonarによって報告されたそのクラスのカバレッジはそのクラスに対してゼロになります

Powermockito Wiki

JavassistをByteBuddy(#727)に置き換えます。この古い問題の解決に役立つはずです。しかし、現時点では、JaCoCoのオンザフライ計測でPowerMockを使用する方法はありません。また、IDEでコードカバレッジを取得するための回避策はありません。

したがって、ここでの解決策は、実際のコードをリファクタリングして、そのクラスのインスタンスを返し、静的にモックする静的ファクトリーを使用することです。


コメントに同意してください。
Lathy

Intellijでは問題ありません。
ACV

0

おそらくあなたは単に使うことができます

Mockito.doReturn(value).when(xxx)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.