2

引数を取り、引数からプライベートハッシュマップを作成するクラスがあります。

Public class Table {
  private Map<String, String> map = new HashMap<String, String>();
  private Workbook workbook;
  // approach 1
  Public Table(Workbook workbook) {
    this.workbook = workbook;
    // populate map using workbook
  }

  // approach 2
  Public Table(InputStream is) {
    this.workbook = WorkbookFactory.create(is)
    // Populate map
  }

 // approach 3
 Public Table(File file) {
   this.workbook = WorkbookFactory.create(file)
   // populate map
 }
}

Workbook は Apache Poi Workbook です。junitとmockitoも考慮した最善のアプローチは何でしょうか。

これによると、 http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/コンストラクターで新しいキーワードを避ける必要があるため、アプローチ1に傾いています。しかし、このクラスを使用するためにクライアントに Apache POI の知識を持たせたくありません。

アプローチ 2 と 3 はかなり似ています。これにより、ファイルまたは入力ストリームを渡すことができ、基になる実装について心配する必要がなくなります。しかし、このアプローチではワークブックをモックできないため、モックは難しいでしょうか?

4

2 に答える 2

2

Factory メソッドとコンストラクターを保護することができます。次のようになります。

public class Table {

    private final Map<String, String> map = new HashMap<String, String>();
    private final Workbook workbook;

    // not private for testing.
    Table(Workbook workbook) {
       this.workbook = workbook;
    }

    public static Table create(File file) {
         return new Table(WorkbookFactory.create(file));
    }
}

このようにTableして、モックWorkbookを使用してクラスをテストできますが、それを使用していることをユーザーに公開することはありません;)

@Runwith(MockitoJunitRunner.class)
public class TableTest {
    @Mock
    private Workbook workbook;
    @InjectMocks
    private Table table;

    // do some sweet testing ;D
}
于 2013-04-05T17:28:17.617 に答える
0

このことを考慮:

public class Table {
  private Map<String, String> map = new HashMap<String, String>();
  private Workbook workbook;

  Table(Workbook workbook) {
    this.workbook = workbook;
    // populate map using workbook
  }

  public Table(InputStream is) {
       this(WorkbookFactory.create(is)) ;
  }

 public Table(File file) {
     this(new FileInputStream(file);
 }
}

Workbook 固有のコンストラクターはパッケージ保護として宣言されているため、通常のクライアントはそれを呼び出すことができませんが、ユニット ケースがライブラリと同じパッケージを共有している場合は、そのコンストラクターをユニット テストから直接呼び出すことに問題はありません。 . これにより、他の 2 つのコンストラクターに対して個別の単体テストを作成することもできます。

于 2013-04-05T17:34:53.503 に答える