2015-12-15 94 views
0

我正在尝试确定编写可测试代码的最佳方法。这里是我的代码在这种情况下编写可测试代码

class FileReader { 

    private FileInputStream input; 

    public FileReader(FileInputStream input) { 
     this.input = input; 
    } 

    public void read() throws IOException { 
     Row row = readHeaderRow(); 
     Row[] rows = readOtherRowsBasedOnHeader(row); 
     doSomethingElse(rows); 
    } 

    private void readHeaderRow() { 
     //.. 
    } 
    private void readOtherRowsBasedOnHeader(Row row) { 
     //.. 
    } 
    private void doSomethingElse(Row[] rows) { 
     //.. 
    } 
} 

从上面可以看出,只有read()方法是公共的。其余的方法是私人的。我应该将私人方法从测试中解脱出来吗?或者是否有意义使所有方法公开并执行read()在调用代码中执行的操作?

+2

为了编写可测试的代码,不应该使方法成为公共或私有方法。你总是可以使用Reflection来测试你的类的私有方法。 – vk239

+0

像Junit/TestNG这样的测试框架是否支持这种基于反射的开箱测试? – Jay

+1

这是一个链接,其中有一篇关于使用Junit和反射测试私有方法的文章 - http://www.jroller.com/CoBraLorD/entry/junit_testing_private_fields_and – vk239

回答

1

类如果私有方法的逻辑(readHeaderRowreadOtherRowsBasedOnHeader,...)是复杂的,我建议实施FileReader作为composition较小类别的单独测试。它会是这样的:

class FileReader { 

private FileHeaderReader headerReader = new FileHeaderReader(); 
private FileOtherReader otherReader = new FileOtherReader(); 
//.... 
private FileInputStream input; 

public FileReader(FileInputStream input) { 
    this.input = input; 
} 

public void read() throws IOException { 
    Row row = headerReader.read(); 
    Row[] rows = otherReader.read(row); 
    //do something else 
} 
} 

class FileHeaderReader { 
    public Row read() {...} 
} 
//.... 

然后,你可以编写测试,精确地测试每个部分/类的逻辑。你也可以考虑将injectingFileHeaderReader纳入FileReader,所以这些类没有紧密耦合。

+0

我想到了这个,但我想如果我继续这样做,我最终会发生类爆炸。 – Jay

+0

这不是一个通用的解决方案。只是其中的一个。总是用你的思想来决定哪种方式最好。无论如何不要害怕参加很多课程,并且记住对象组合通常会导致更多的可测试代码。 –

1

如果公共方法的测试涵盖了私有方法的所有代码,是安全的考虑测试

+0

好吧,非常有效的答案。 – Jay

2

我的看法是,你应该只测试公共方法。不管来自公共方法的调用,都会测试私有方法的使用情况。它也将使内部重构更容易,而无需更改测试。

你想测试的是该类履行其合同,即。公共方法,无论它在内部看起来如何。

1

我看到两个可行的选项。

  1. 您测试阅读(),让您的测试应覆盖条件和私方法的国家改变。无论你想要这样做,这都取决于这些方法的责任和复杂性。
  2. 你会发现那些私人方法违反SRP并将它们分开,以便它们现在在不同的类中公开。