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 工作簿。考虑到junit和mockito的最佳方法是什么。

我倾向于方法 1,因为根据这个,http ://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/我应该避免在构造函数中使用 new 关键字。但我不希望客户了解 Apache POI 才能使用此类。

方法 2 和 3 非常相似。有了这个,我可以传入文件或输入流,而不必担心底层实现。但是模拟会很困难,因为我不能用这种方法模拟工作簿?

4

2 回答 2

2

您可以创建一个工厂方法并且您的构造函数受到保护。会是这样的:

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);
 }
}

请注意,工作簿特定的构造函数被声明为包保护,因此普通客户端将无法调用它,但如果您的单元案例与您的库共享相同的包,则直接从单元测试调用该构造函数将没有问题. 这也将允许您为其他两个构造函数编写单独的单元测试。

于 2013-04-05T17:34:53.503 回答