NSubstitute:模拟私有方法

NSubtitute: Mock private method

我正在使用 NSubtitute,我想测试一个调用私有方法的方法(在相同 class 中),因为私有方法调用 SSRS 生成报告,在实际情况下,它可以工作,但是我不想在单元测试中调用真实的报表服务器,所以我想模拟它。

public static byte[] GenerateFinanceReport(long financeId, long userId, string currentLanguage, ReportDataVO reportDataVO, string reportName)
{
    var parameterValues = SetStandardParameters(userId, currentLanguage, reportDataVO);

    var paramFinanceId = new ParameterValue
    {
        Value = financeId.ToString(),
        Name = ParamFinanceId
    };
    parameterValues.Add(paramFinanceId );

    return GenerateReport(reportDataVO, parameterValues, reportName);
}


private static byte[] GenerateReport(ReportDataVO reportDataVO, List<ParameterValue> parameterValues, string reportName)
{
    var reportSerive = new ReportExecutionService.ReportExecutionService
    {
        Credentials = CredentialCache.DefaultNetworkCredentials,
        ExecutionHeaderValue = new ExecutionHeader()
    };
    reportSerive.LoadReport(reportName, null);
    ...
    return reportSerive.Render(...);
}

我想模拟调用 return GenerateReport(reportDataVO, parameterValues, reportName),并且能够使用 NSubtitute 的 Receive 方法检查每个测试用例的此调用的参数输入。

我们必须重构代码并将 'GenerateReport' 方法移动到新的 class 例如 GenerateReportService 通过接口实现 ]IGenerateReportService 以模拟该方法并注入 class,如下所示。

public class Class2bTested
{
    IGenerateReportService _IGenerateReportService;
    public (IGenerateReportService IIGenerateReportService)
    {
         _IIGenerateReportService=IIGenerateReportService;
    }

    public byte[] GenerateFinanceReport(long financeId, long userId, string currentLanguage, ReportDataVO reportDataVO, string reportName)
    {
        var parameterValues = SetStandardParameters(userId, currentLanguage, reportDataVO);

        var paramFinanceId = new ParameterValue
        {
            Value = financeId.ToString(),
            Name = ParamFinanceId
        };
        parameterValues.Add(paramFinanceId );

        return _IGenerateReportService.GenerateReport(reportDataVO, parameterValues, reportName);
     }
 }

新的class如下:

  public interface IGenerateReportService
  {
      GenerateReport(ReportDataVO reportDataVO, List<ParameterValue> parameterValues, string reportName);
  }    
  public class GenerateReportService:IGenerateReportService
  {
       public byte[] GenerateReport(ReportDataVO reportDataVO, List<ParameterValue> parameterValues, string reportName)
        {
         var reportSerive = new ReportExecutionService.ReportExecutionService
         {
               Credentials = CredentialCache.DefaultNetworkCredentials,
                ExecutionHeaderValue = new ExecutionHeader()
         };
         reportSerive.LoadReport(reportName, null);

          return reportSerive.Render();
}

有了这段代码,现在我们可以模拟 IGenerateReportService 的方法 GenerateReport