Java 如何模拟正在测试的类的继承方法

Java 如何模拟正在测试的类的继承方法,java,junit,mocking,mockito,powermock,Java,Junit,Mocking,Mockito,Powermock,我有类似的代码 class Util{ public String transform(String str); //lots of logic including ajax calls return("Modified"+str); } public caseChange(String str){ //lots of logic including ajax calls return str.toUpperCase() } class TextParser ext

我有类似的代码

class Util{
 public String transform(String str);
 //lots of logic including ajax calls
 return("Modified"+str);
 }
 public caseChange(String str){
 //lots of logic including ajax calls
 return str.toUpperCase()      
 }

class TextParser extends Util{
 public String parse(str)
//lots of logic to modify str
 str = caseChange(str);
 //some more logic to modify str
return transform(str);
}
是否仍然需要模拟caseChange和transform方法来返回一些模拟的数据,并防止在调用时调用超类

String result = new TextParser().parse("hello")
在单元测试类中断言结果


在我的示例中,transform和changeCase过于简化。实际上,它们执行ajax调用,还有大量其他逻辑。我想模拟它们,这样就可以只对这一部分进行单元测试,然后在您给定的示例中对超级方法进行单元测试:您根本不需要这样做。你的方法只对你的输入起作用;因此,无论这些方法在哪里实施,都应该绝对无所谓

换句话说:您只关注合同检查似乎是最合适的。比如:

@Test
public testWhatever() {
  assertThat(new TextParser.parse("hello"), is("expected output"));
}
是的,您可能可以使用Mockito/Powermock来模拟这些东西;但你不应该!你看,你的生产代码直接调用这些方法;因此,您希望测试调用parse是否会给您带来预期的结果(同时使用也将在生产设置中运行的所有代码!)

编辑:鉴于您对该方法“复杂”的评论。然后我建议:不要在这里使用继承。您应该而不是使类B成为a的子类,以便轻松访问某些方法。换句话说:继承就是对一个is-A关系进行建模。那么,TextParser是Util吗?听起来不是很有说服力


因此,你最好在这里转向构图。TextParser应该使用Util对象。并且可以通过依赖注入来提供依赖注入;你需要用继承的方法来模仿的需求完全消失了

您可能需要创建另一个子类,如

class TextParserForTest extends TextParser {
      @Override
      public String parse(String str)  {
              super.parse(str);
      }

      @Override
      public String caseChange(String str) {
              return "whatever";
      }
}

编辑:使用mockito编辑以下内容:

import static org.mockito.Mockito.*;

import org.junit.Test;

@Test
public void test() {
    TextParser tp = mock(TextParser.class);

    // all the methods that you want to test
    when(tp.parse(any())).thenCallRealMethod();
    when... 

    // all the methods that you want to mock
    when(tp.caseChange(any()).thenReturn("whatever");
    when... 
}

您可以使用Mockito的间谍功能。间谍调用真正的方法,除非它们被截短

@Test
public void testParse() {   
    TextParser textParser = Mockito.spy(new TextParser());          
    when(textParser.caseChange(Matchers.anyString())).thenReturn("mocked");
    Assert.assertEquals("Modifiedmocked", textParser.parse("hello"));
}

在我的示例中,transform和changeCase过于简化。实际上,它们执行ajax调用,还有大量其他逻辑。我想模拟它们,这样就可以只对这一部分进行单元测试,然后再对超级方法进行单元测试。我必须为每个类编写25个测试用例:(有没有任何方法可以使用powermock或mockito进行测试?请尝试when(textParse.caseChange(anyString())。然后返回(“任意”);我用一个新的Util和TextParser对象尝试了这个方法。它仍然会转到super classI添加了一些东西,你可以试试