Thien Long
Thien Long

Reputation: 349

NSubtitute: Mock private method

I am using NSubtitute, I want to test a method that calls a private methods (in same class), as the private method calls a SSRS to generate report, in real case, it works, but I don't want to call to a real report server in unit test, so I would like to mock it.

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(...);
}

I want to mock the call return GenerateReport(reportDataVO, parameterValues, reportName), and able to use Receive method of NSubtitute to check of parameters input to this call for each test cases.

Upvotes: 0

Views: 474

Answers (1)

Ajeet Kumar
Ajeet Kumar

Reputation: 729

We shall have to refactor the code and move the 'GenerateReport' method to a new class e.g.GenerateReportService by implementing through interface e.g.IGenerateReportService in order to mock the method and inject the class as below.

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);
     }
 }

The new class shall be as below:

  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();
}

With this code in place now we can mock IGenerateReportService's method GenerateReport

Upvotes: 3

Related Questions