0

mainから呼び出されることをモックアウトしたい機能がいくつかあります(静的:それについても読みました-静的メソッドをモックするjmock)。最近、JMockが静的関数のモックをサポートしていないことを読みました。さて、関連するコード(それは私に問題を与えています)はmainから呼び出されなければならず、mainのクラスになければなりません...

サンプルソース

テストコード

今のところ、ファイルが進む前にファイルが存在することを確認するためのテストがメインにあることを確認したいと思います。問題は、プログラムがコンソールからユーザー入力を取得しているので、それをモックアウトする方法がわからないということです。ユーザーの入力を返す関数で1つの操作についてのみ記述できるように、そのレベルの粒度まで下げて、何が起こるかをすべてのポイントで指定しますか?テストをうまく書くために、テストが実行されるとき、彼らはユーザー入力を求めてはいけないことを知っています、私はどういうわけか私のテストでそれを指定するべきです。

私はそれが次のことに関係していると思います: JMockを使用してモックされたメソッド内のモックされたメソッドをテストする方法 私はJMockがあまり得意ではありません...

4

3 に答える 3

2

メソッドが次のようなことを行う場合、次のreadInput()ように言います。

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
return in.readLine();

そうすれば、次のようなテストで逃げることができるかもしれません。

InputStream oldSystemIn = System.in;
InputStream mockSystemIn = context.mock(InputStream.class);
System.setIn(mockSystemIn);
context.checking(new Expectations() {{
    // mock expected method calls and return values
}});
// execute
// verify
System.setIn(oldSystemIn);
于 2012-04-21T04:44:48.183 に答える
1

System.outとSystem.inをモックする代わりに、システムルールを使用できます。

public void MyTest {
  @Rule
  public TextFromStandardInputStream systemInMock = emptyStandardInputStream();

  @Test
  public void readTextFromStandardInputStream() {
    systemInMock.provideText("your file name");
    //your code that reads "your file name" from System.in
  }
}
于 2012-04-21T23:39:50.313 に答える
0

ステファン・ビルクナーの答えは、私がこれを解決できるようにする必要があるという方向性を私に与えました。これを解決するために使用したコードを以下に投稿しました。

解決済みのテスト:Birknerのバージョン(推奨

解決済みのテスト:パイプバージョン

変更されたソース:

理由: Birknerのライブラリでは、元々ルールを使用してインスタンス化したのと同じ量の入力しか読み取ることができません。エンドポイントに繰り返し書き込む場合は、パイプハックを使用してこれを行うことができますが、大した違いはありません。関数が実際に実行されている間は、パイプを介して入力に書き込むことができないため、 Birknerのバージョンを使用するのもよいでしょうが、彼の@Ruleはより簡潔です。

説明:パイプハックとBirknerのコードの両方で、テスト対象のクライアントで、System.inから読み取るオブジェクトを作成するための複数の呼び出しにより、最初のオブジェクトがパイプまたはへの接続を開くと、ブロッキングの問題が発生します。 System.in、他の人はできません。これがBirknerのコードに正確に当てはまる理由はわかりませんが、Pipeを使用すると、オブジェクトに対して1つのストリームしか開くことができないためだと思います。最初のバッファリングされたリーダーでcloseを呼び出し、テストから呼び出した後にクライアントコードでSystem.inを再度開こうとすると、ライター側のパイプが閉じられているため、2回目の開こうは失敗することに注意してください。同じように。

解決:これを解決する簡単な方法です。実際のプロジェクトのソースを変更する必要があるため、おそらく最善ではありませんが、恐ろしい方法ではありません(まだ)。したがって、実際のプロジェクトのソースに複数のBufferedReaderを作成する代わりに、バッファリングされたリーダーを作成し、同じリーダー参照を渡すか、クラスのプライベート変数にします。静的に宣言する必要がある場合は、静的コンテキストで初期化しないでください。初期化すると、テストの実行時に、リーダーがクライアントで初期化された後にSystem.setInが呼び出されます。したがって、System.inから複数のオブジェクトを作成しようとした場合と同じように、すべてのreadLine/すべての呼び出しでポーリングします。リーダー(この場合はBufferedReader)からの呼び出し間で読み取りを分離することに注意してください。改行を使用して、元の設定でそれらを分離できます。このようにして、テスト対象のクライアントでの各呼び出しで必要なものを返します。

于 2012-04-22T04:45:15.150 に答える