Java 如何针对代码流中的不同结果模拟私有方法

Java 如何针对代码流中的不同结果模拟私有方法,java,mocking,powermock,private-methods,Java,Mocking,Powermock,Private Methods,我的java代码中有一个私有方法,需要调用两次。我正在使用Powermock编写junits。在模拟上述方法时,我需要两个不同的调用结果 //我试过: PowerMockito.doReturn("MyString1").doReturn("MyString2").when(spy,"getresult",Mockito.anyString()); //但是当()不接受spy对象以外的任何对象时 PowerMockito.doReturn("MyString1").doReturn("MySt

我的java代码中有一个私有方法,需要调用两次。我正在使用Powermock编写junits。在模拟上述方法时,我需要两个不同的调用结果

//我试过:

PowerMockito.doReturn("MyString1").doReturn("MyString2").when(spy,"getresult",Mockito.anyString());
//但是当()不接受spy对象以外的任何对象时

PowerMockito.doReturn("MyString1").doReturn("MyString2").when(spy).getresult(Mockito.anyString());
//when()不允许使用方法getresult,因为此getresult方法已声明为私有

代码

Class A{
String firstString="abc";
String secondString="def";
String result1=getresult(firstString);
String result2=getresult(secondString);

private String getresult(String arg1){
//My code here;
return "AnyString";
}
}
JUNIT

//Declarations
@InjectMocks
A a;
.......
@Test
public void ATest(){
....
/*Suppose I want "MyString1" and "MyString2" as result for calling the method "getresult" for result1 and result2 in Class A*/
A spy=PowerMockito.spy(a);
PowerMockito.doReturn("MyString1").when(spy,"getresult",Mockito.anyString());
....
}
// Please overlook the typos
使用我尝试过的代码时出现编译错误。 正如在代码注释中所写的,我期望在两个连续的方法调用中得到两个结果“MyString1”和“MyString2”,如代码所示


提前谢谢。任何其他实现结果的方法都是值得赞赏的。

首先让我注意使用
PowerMock
的主要原因是帮助测试遗留应用程序。在一个新的代码中根本没有
PowerMock
的位置。在新代码中需要
PowerMock
,这表明设计中存在严重问题

单元测试的一个好处是,测试提供了对设计的反馈。如果编写这样的测试过于笨拙、脆弱或不可能(没有
PowerMock
),您应该重新考虑您的设计


测试此类代码可以做的一件事是将私有方法提取到单独的类中,并将其作为依赖项提供。那你就可以轻松地嘲笑它了。但是您仍然应该测试提取的逻辑,这取决于您为什么不能首先设置测试。您可能需要集成测试或其他方法。

我通常不单独测试私有方法。它们将由调用此私有方法的公共方法进行测试。如果有多个流,则以测试私有方法中所有代码路径的方式编写多个测试

但是,下面的链接显示了如何测试私有方法


您不应该模拟私有方法您不应该模拟/测试私有方法,它们是被测试单元的实现细节,您的测试将与实际实现紧密耦合。实际上,私有方法需要一些junits中无法提供的参数。这就是为什么我要嘲笑这个方法。谢谢。不,那个论点是无效的,私有方法不重要。问题是你的班级结构是错误的。使用可能复杂的方法调用初始化自己的字段不是一个好主意。@SwastikBanerjee您的私有方法在公共方法中被调用,是它们向它们传递信息。“无法在junits中提供的参数”。。。对于私有方法,这是毫无意义的“在新代码中需要PowerMock表明设计中存在严重问题”。不,那是胡说八道。如果您不使用模拟框架来测试代码,那么您要么没有任何服务调用,要么没有任何单元测试。记住,单元测试应该测试单元,而不是测试单元背后的所有内容。这就是端2端测试的目的。我是专门谈论PowerMock,而不是一般意义上的mocking。无论你谈论Mockito还是PowerMock,在声明它们的用途之前,你可能希望阅读它们官方页面上的评论(PowerMock不主要用于遗留应用程序。(无论如何,不是根据它们的页面)@Stultuske Januson的观点是,对于新的和正确编写的代码,像Mockito这样的东西应该足够了。必须使用更强大的工具(例如mocks静态方法)表示代码有缺陷,因为您不应该使用更强大的功能。PowerMock的制造商是否这样认为并不重要。