関数 (副作用のないもの) は基本的なビルディング ブロックですが、Java でそれらをテストする満足のいく方法を知りません。
テストを簡単にするトリックへのポインタを探しています。これが私が欲しいものの例です:
public void setUp() {
myObj = new MyObject(...);
}
// This is sooo 2009 and not what I want to write:
public void testThatSomeInputGivesExpectedOutput () {
assertEquals(expectedOutput, myObj.myFunction(someInput);
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
// I don't want to repeat/write the following checks to see
// that myFunction is behaving functionally.
assertEquals(expectedOutput, myObj.myFunction(someInput);
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
}
// The following two tests are more in spirit of what I'd like
// to write, but they don't test that myFunction is functional:
public void testThatSomeInputGivesExpectedOutput () {
assertEquals(expectedOutput, myObj.myFunction(someInput);
}
public void testThatSomeOtherInputGivesExpectedOutput () {
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
}
テスト、MyObject、または myFunction に付けることができる注釈を探しています。これにより、テスト フレームワークは、指定した入力/出力の組み合わせ、または一部のサブセットに対して、可能なすべての順列で myFunction への呼び出しを自動的に繰り返すことができます。関数が機能的であることを証明するための可能な順列。
たとえば、上記の (唯一の) 2 つの可能な順列は次のとおりです。
- myObj = new MyObject();
- myObj.myFunction(someInput);
- myObj.myFunction(someOtherInput);
と:
- myObj = new MyObject();
- myObj.myFunction(someOtherInput);
- myObj.myFunction(someInput);
入力/出力のペア (someInput、expectedOutput)、および (someOtherInput、someOtherOutput) のみを提供できる必要があり、残りはフレームワークが行う必要があります。
QuickCheck を使用したことはありませんが、解決策ではないようです。ジェネレーターとして文書化されています。関数への入力を生成する方法を探しているのではなく、オブジェクトのどの部分に副作用がないかを宣言的に指定し、その宣言に基づく順列を使用して入出力仕様を呼び出すことができるフレームワークを探しています。
更新: オブジェクトに何も変更がないことを確認するつもりはありません。メモ化関数はこの種のテストの典型的なユースケースであり、メモライザーは実際に内部状態を変更します。ただし、何らかの入力が与えられた場合の出力は常に同じままです。