如何测试和模拟递归方法?

Hen*_*ano 3 java mockito

我尝试模拟这种方法,但我不知道如何构建它...我使用 Mockito 和 jUnit。

有没有办法以简单的方式做到这一点?

非常感谢。


public Object getColumnValue(ReportRow row, String columnId, Vector errors) 
{

        if (HSBC_PAYREC.equals(columnId)) {
            String s = (String) getColumnValue(row, "Pay/Rcv", errors);
            if (s != null) {
                if (s.equals("Pay")) {
                    return "Receive";
                }
            }
            return "";
        }
}
Run Code Online (Sandbox Code Playgroud)

Jef*_*ica 5

因为您正在测试被测系统,所以模拟被测系统没有任何意义。我认为可以公平地说这包括模拟对被测系统的递归调用。(除了在哲学上非常奇怪之外,您可能很难确保在测试中调用未模拟版本,同时确保未模拟版本在尝试调用自身时调用模拟版本。)最好的办法是重构您的测试,以便递归行为是您预期行为的一部分。

也就是说,虽然它确实使代码更难遵循,但您确实有两种选择。一个涉及部分模拟:

public Object getColumnValue(ReportRow row, String columnId, Vector errors) {
  if (HSBC_PAYREC.equals(columnId)) {
    String s = (String) getColumnValueRecursively(row, "Pay/Rcv", errors);
    if (s != null) {
      if (s.equals("Pay")) {
        return "Receive";
      }
      if (s.equals("Receive")) {
        return "Pay";
      }
      return "";
    }
  }
}

/** For testing. */
Object getColumnValueRecursively(ReportRow row, String columnId, Vector errors) {
  return getColumnValue(row, columnId, errors);
}
Run Code Online (Sandbox Code Playgroud)

在测试中:

@Test public void yourTest() {
  SystemUnderTest yourSystemUnderTest = Mockito.spy(new SystemUnderTest());
  doReturn(yourMockedValue).when(yourSystemUnderTest).getColumnValueRecursively(
      /* your recursive base case */);
  // ...
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,我想您可以在不创建间接递归的情况下做到这一点,但是您正在根据参数切换行为,这使得确保您的测试有效变得更加困难。你的另一个选择同样棘手:

SystemUnderTest recursiveInstance = this; // replace with a mock within test

public Object getColumnValue(ReportRow row, String columnId, Vector errors) {
  if (HSBC_PAYREC.equals(columnId)) {
    String s = (String) recursiveInstance.getColumnValue(row, "Pay/Rcv", errors);
    if (s != null) {
      if (s.equals("Pay")) {
        return "Receive";
      }
      if (s.equals("Receive")) {
        return "Pay";
      }
      return "";
    }
  }
}
Run Code Online (Sandbox Code Playgroud)