Moq 具有 SQL 调用 c# 的方法

Moq a method having SQL call c#

我正在尝试 Moq 一个正在调用 SQL 但无法调用的方法:

下面是Moq/Unit测试代码:

DataTable dataTable = new DataTable();
Mock<IDataAccessHelper> mockDataAccessHelper = new Mock<IDataAccessHelper>();
mockDataAccessHelper.Setup(x => x.ExtractDataFromDB(It.Is<string>(query => query.Contains("StudentTable")), It.IsAny<object[]>())).Returns(dataTable);

// This is the data access class from where I am calling the ExtractDataFromDB method which I want to Moq
IDataAccess dataAccess = new DataAccess();
object[] studentIds = new object[] {100,101,102};
List<Student> studentData= dataAccess.GetData(studentIds);

单元测试代码如下:

public class DataAccess : IDataAccess
{
    private IDataAccessHelper DataAccessHelper { get; set; }

    public DataAccess()
    {
        DataAccessHelper = new DataAccessHelper();   
    }

    public List<Student> GetData(object[] studentIds)
    {
       string query = "SELECT StudentName,Address,Marks FROM StudentTable WHERE StudentId = @StudentId"
       DataTable table = DataAccessHelper.ExtractDataFromDB(query,studentIds);
       List<Student> studentList = (from DataRow dr in dt.Rows  
       select new Student()  
       {  
            StudentName = dr["StudentName"].ToString(),  
            Address = dr["Address"].ToString(),  
            Marks= Convert.ToInt32(dr["Marks"])  
       }).ToList(); 
       return studentList;
    }
}

public interface IDataAccessHelper
{
   DataTable ExtractDataFromDB(string query,object[] values);
}

public class DataAccessHelper : IDataAccessHelper
{
    public DataTable ExtractDataFromDB(string query,object[] values)
    {
        foreach(var id in values)
        {  
           // SQL Call
        }
    }
}

所以我想测试 GetData 方法来检查 StudentList 中的学生 ID 列表,并在其中尝试对具有 SQL 调用的 ExtractDataFromDB 方法进行 moq。

有帮助吗???

为了实现这一点,您需要通过 dependency-injection(例如 constructor-injection)向您的 DataAccess 实例提供 DataAccessHelper。不要让您的实例创建其依赖项:

private IDataAccessHelper DataAccessHelper { get; }

public DataAccess(IDataAccessHelper helper)
{
    DataAccessHelper = helper;
}

现在您可以为您的 DataAccess-实例提供该接口的任何实现:

IDataAccess dataAccess = new DataAccess(myMockForDataBaseHelper);
object[] studentIds = new object[] {100,101,102};
List<Student> studentData= dataAccess.GetData(studentIds);

或者 - 因为您已经有一个 属性 来注入助手 - 您可以在创建 DataAccess- 实例后提供助手。这称为 property-injection,与前面提到的 constructor-injection 相对。但是,您必须使 属性 public:

public IDataAccessHelper DataAccessHelper { get; set; }

public DataAccess()
{
    DataAccessHelper = new DataAccessHelper();   
}

在你的测试中:

IDataAccess dataAccess = new DataAccess();
dataAccess.DataAccessHelper = myMockForDataBaseHelper;
object[] studentIds = new object[] {100,101,102};
List<Student> studentData= dataAccess.GetData(studentIds);