使用企业库返回 IDataReader 的模拟数据访问方法



我被赋予了一个重写 API 和相应单元测试的任务。我对单元测试还很陌生,因此我正在努力为使用企业库的数据访问类编写测试代码。这是代码:

namespace TOS_Landside_BL.Classes {
  using System.Collections.Generic;
  using System.Data;
  using System.Data.Common;
  using Microsoft.Practices.EnterpriseLibrary.Data;
  using Interfaces;
  public class DataAccess : IDataAccess {
    private readonly Database yasDB;
    public DataAccess () {
      DatabaseProviderFactory factory = new DatabaseProviderFactory ();
      DatabaseFactory.SetDatabaseProviderFactory (factory, false);
      yasDB = factory.Create ("AutomationDB");
    }
    // caller is responsible for closing the reader.
    public IDataReader ExecuteReaderForStoredProcedure (string cmdName, List<DbParameter> parameters = null) {
      DbCommand cmd = yasDB.GetStoredProcCommand (cmdName);
      if (parameters != null)
        cmd.Parameters.AddRange (parameters.ToArray ());
      return yasDB.ExecuteReader (cmd);
    }
    public IDataReader ExecuteReaderForSqlStringCommand (string cmdScript, List <DbParameter> parameters = null) {
      DbCommand cmd = yasDB.GetSqlStringCommand (cmdScript);
      if (parameters != null) {
        cmd.Parameters.AddRange(parameters.ToArray());
      }
      return yasDB.ExecuteReader (cmd);
    }
  }
}

这是界面 IDataAccess:

namespace TOS_Landside_BL.Interfaces {
  using System.Collections.Generic;
  using System.Data;
  using System.Data.Common;
  public interface IDataAccess {
    IDataReader ExecuteReaderForStoredProcedure (string cmdName, List<DbParameter> parameters = null);
    IDataReader ExecuteReaderForSqlStringCommand (string cmdScript, List <DbParameter> parameters = null);
  }
}

以下是我如何称呼它的示例:

namespace TOS_Landside_BL.Data {
  using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Data.Common;
  using System.Data.SqlClient;
  using System.Linq;
  using Classes;
  using Enums;
  using Factories;
  using Interfaces;
  public class LandsideTransactionDataProvider {
    private readonly IDataAccess _dataAccess;
    public LandsideTransactionDataProvider (IDataAccess dataAccess = null)  
    {
      _dataAccess = dataAccess ?? new DataAccess ();
    }
    public LandsideTransaction GetLandsideTransaction (string keyword, bool isKioskID = false)
    {
      var strCmd = isKioskID ? "proc_get_landside_transaction_by_kiosk_id" : "[LandSide].[GetLandsideTransactionDetail]";
      var parameters = new List <DbParameter> () {
        new SqlParameter ("@keyword", SqlDbType.NVarChar, 11) {Value = keyword}
      };
      using (var reader = _dataAccess.ExecuteReaderForStoredProcedure (strCmd, parameters)) {
        return reader.Read () ? reader.CreateLandSideTransaction () : null;
      }
    }
  }

在我的测试类的 SetUp 方法中,我尝试了这个:

var dataAccess = new Mock<IDataAccess>();
dataAccess.SetUp(d => d.ExecuteReaderFromStoredProcedure(null, null)).Returns(IDataReader);

但它不接受 IDataReader 或任何具体的数据读取器类。

请告知我做错了什么,任何建议将不胜感激。 谢谢。

您可以为IDataReader创建模拟,也可以为测试进行设置。

var reader = new Mock<IDataReader>();
//..Setup the reader as expected for the test.
//Like reader.Read(), etc.
var dataAccess = new Mock<IDataAccess>();
dataAccess
    .Setup(_ => _.ExecuteReaderForStoredProcedure(It.IsAny<string>(), It.IsAny<List<DbParameter>>()))
    .Returns(reader.Object);//return mocked reader.

最新更新