Moq具有SQL调用c#

时间:2019-07-11 11:55:57

标签: c# .net moq

我正在尝试Moq一种具有SQL调用但无法执行的方法:

下面是Moq /单元测试代码:

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方法进行定量。

有帮助吗?

1 个答案:

答案 0 :(得分:2)

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

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实例后提供帮助程序。这称为属性注入,与之前提到的构造函数注入相反。但是,您必须设置属性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);