首页 > 解决方案 > 最小起订量具有 SQL 调用 c# 的方法

问题描述

我正在尝试 Moq 一种具有 SQL 调用但不能这样做的方法:

以下是起订量/单元测试代码:

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 列表,并且在其中我试图 moq 具有 SQL 调用的 ExtractDataFromDB 方法。

有什么帮助???

标签: c#.netmoq

解决方案


为了实现这一点,您需要向您的-instance提供DataAccessHelper通过依赖注入(例如构造函数注入) 。DataAccess不要让您的实例创建其依赖项:

private IDataAccessHelper DataAccessHelper { get; }

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

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

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

或者 - 因为您已经有一个属性来注入帮助程序 - 您可以在DataAccess创建 -instance 后提供帮助程序。这称为属性注入,与前面提到的构造函数注入相反。但是你必须使财产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);

推荐阅读