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
我正在使用 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