これは非常に一般的なテストの問題であり、これに対して私が遭遇する最も一般的な解決策は、依存性注入を使用してデータを使用するコードからデータのソースを分離することです。これは、優れたテストをサポートするだけでなく、一般的に、外部データ ソースを操作する際の優れた戦略です (責任の適切な分離、統合ポイントの分離、コードの再利用の促進など、いくつかの理由があります)。
必要な変更は次のようになります。
- データ ソースごとに、そのソースからのデータへのアクセス方法を定義するインターフェイスを作成し、データを返すコードを、これを実装する別のクラスに分解します。
- 依存関係により、「長い」関数を含むクラスにデータ ソースが挿入されます。
- 単体テストでは、各データ ソースのモック実装を挿入します。
これがどのようになるかを示すいくつかのコード例を次に示します。このコードは単なるパターンの例であることに注意してください。物事にはもっと適切な名前が必要になります。このパターンを研究し、依存性注入とモッキング (ユニット テスターの武器庫で最も強力な 2 つの武器) についてさらに学ぶことは価値があります。
データ ソース
public interface DataSourceOne {
public Data getData();
}
public class DataSourceOneImpl implements DataSourceOne {
public Data getData() {
...
return data;
}
}
public interface DataSourceTwo {
public Data getData();
}
public class DataSourceTwoImpl implements DataSourceTwo {
public Data getData() {
...
return data;
}
}
Long メソッドを持つクラス
public class ClassWithLongMethod {
private DataSourceOne dataSourceOne;
private DataSourceTwo dataSourceTwo;
public ClassWithLongMethod(DataSourceOne dataSourceOne,
DataSourceTwo dataSourceTwo) {
this.dataSourceOne = dataSourceOne;
this.dataSourceTwo = dataSourceTwo;
}
public Result longMethod() {
someData = dataSourceOne.getData();
someMoreData = dataSourceTwo.getData();
...
return result;
}
}
単体テスト
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ClassWithLongMethodTest {
@Test
public void testLongMethod() {
// Create mocked data sources which return the data required by your test
DataSourceOne dataSourceOne = mock(DataSourceOne.class);
when(dataSourceOne.getData()).thenReturn(...);
DataSourceTwo dataSourceTwo = mock(DataSourceTwo.class);
when(dataSourceTwo.getData()).thenReturn(...);
// Create the object under test using the mocked data sources
ClassWithLongMethod sut = new ClassWithLongMethod(dataSourceOne,
dataSourceTwo);
// Now you can unit test the long method in isolation from it's dependencies
Result result = sut.longMethod();
// Assertions on result
...
}
}
構文上の誤りがあればご容赦 (および訂正) してください。最近はあまり Java を作成していません。