2017-03-03 51 views
1

我在单元测试下面的方法时遇到了一些问题。java - testing - 使用内部私有方法的lambda?

public List<GetSupplyChainResponse> getSupplyChains(){ 
    List<GetSupplyChainsResponse> response = new ArrayList<>(); 
    supplyChainRepository.findSupplyChainsWithCompound().forEach(result 
      -> response.add(getGetSupplyChainSimpleResponse(result))); 

    return response; 
} 

getGetSupplyChainSimpleResponse()是同一类的getSupplyChains()的私有方法

是否有可能因此或者你有任何其他想法,我怎么能测试方法getSupplyChains()定义的返回值?

+0

您可以使用反射。看到这个http://stackoverflow.com/questions/11282265/how-to-call-a-private-method-from-outside-a-java-class –

+0

你有什么问题?你有什么错误吗?也许你还想显示'getGetSupplyChainSimpleResponse()'方法,这样我们就可以看到那里发生了什么。 – px06

+0

如果没有调用'private'方法的lambda表达式,则测试getSupplyChains()方法的方式与测试方法完全相同。 – Holger

回答

-1

这是一个普遍讨论的问题,有些人更喜欢使用反射,因为Janos Binder建议(How to call a private method from outside a java class),有些人可以忍受我们需要模拟的方法的可见性为了可测性而增加。

这个问题在这里讨论得很好:How do I test a class that has private methods, fields or inner classes?。你可以从答案和广泛的讨论中看到,这个话题非常复杂,开发者分裂成派别并使用不同的解决方案。

我建议您删除private访问修饰符并使方法包为私有(使用默认的可见性)。常见的习惯是将测试类与测试类放在同一个包中(但不在同一个文件夹!)。

这将允许您:

  1. 测试getGetSupplyChainSimpleResponse()方法本身,你应该在任何情况下做不知。

  2. 为了测试getSupplyChains()而模拟其行为。这将会达到例如通过使用Mockito框架及其@Spy functionality

对于那些谁认为这是“牺牲你的设计进行测试的缘故”,我会回答如果你有需要私有方法加以嘲笑和/或测试,然后的设计并不理想所以改变包装私人的知名度并不意味着太大的恶化。从面向对象设计的角度来看,清晰的解决方案是将这些私有方法的行为委托给不同的类。但是,有时在现实生活中它只是矫枉过正。

2

你可能会反覆考虑这一点。您想要测试的方法(getSupplyChains)使用调用私有方法的lambda是无关紧要的事实:它们只是实现细节。

单元测试是您作为客户端与之交互的类的一部分,即其接口。你通常使用一些参数调用一个公共方法(在这个例子中没有),你会得到一些返回值,这就是你在单元测试中验证的东西。如果你的公开方法使用一些私人方法,它也将被测试

这里的问题是您从getSupplyChains获得的回答显然取决于supplyChainRepository.findSupplyChainsWithCompound()返回的内容。你在这种情况下所做的就是模拟这种依赖(supplyChainRepository):你创建一个SupplyChainRepository的模拟实例,告诉它如何行为,并将它传递给这个类,例如通过构造函数。

你可以自己写模拟,也可以依靠模拟框架来完成像Mockito这样的繁重工作。我绝对建议不要单元测试私有方法(它会导致脆弱的测试),或者增加这些方法的可见性(也就是为了测试而牺牲你的设计)。