Moq和SqlConnection?

我正在为我们的一个产品编写单元测试,并且已经使用Moq成功地模拟了到Entity Framework的连接。 但是,我遇到了以下方法:

public static productValue findValues(string productName, string dbConnectionString)
{
    try
    {
        SqlConnection conn = new SqlConnection(dbConnectionString);
        conn.Open();
        //Do stuff 
    }
}

它使用传递的连接字符串在该方法内访问我们的数据库。 是否可以使用Moq设置模拟数据库并创建指向模拟数据库的连接字符串? 我一直在努力做一些事情

var mockSqlConnnection = new Mock<SqlConnection>();

虽然我不确定这是否是正确的方法,因为这会嘲笑连接本身而不是数据库。


我有类似的问题。

我从SqlConnection和ISqlDataContext接口继承了一个SqlDataContext包装器:

class SqlDataContext : ISqlDataContext {

    private readonly SqlConnection _connection;

    public SqlDataContext(string connectionString)
    {
        _connection = CreateConnection(connectionString);
    }

    public IDataReader ExecuteReader(string storedProcedureName, ICollection<SqlParameter> parameters)
    {
       // execute the command here using the _connection private field.
       // This is where your conn.Open() and "do stuff" happens.
    }

    private SqlConnection CreateConnection(string connectionString)
    {
        if (string.IsNullOrEmpty(connectionString))
        {
            throw new ArgumentNullException("connectionString");
        }

        return new SqlConnection(connectionString);
    }
}

interface ISqlDataContext
{
    IDataReader ExecuteReader(string storedProcedureName, ICollection<SqlParameter> parameters);
}

您可以根据需要将重载添加到ISqlDataContext。

这意味着你可以使用Moq或类似方法模拟ISqlDataContext,并返回模拟值。

意味着您可以测试您的存储库或其他任何通过SqlConnection访问数据库而不必实际访问数据库的其他数据库。

另一个优点是,您可以根据需要使用DI / IoC注入ISqlContext。


看看Repository Pattern,本质上你会模拟你的消费类中的数据,而不用担心与数据库交谈的实现。


基本上,你会有一个存储库

namespace ContosoUniversity.DAL
{
    public class StudentRepository : IStudentRepository, IDisposable
    {
        private SchoolContext context;

        public StudentRepository(SchoolContext context)
        {
            this.context = context;
        }

        public IEnumerable<Student> GetStudents()
        {
            return context.Students.ToList();
        }

        // ... more

然后在其他类中消耗:

   public class StudentController : Controller
   {
      private IStudentRepository studentRepository;

      public StudentController(IStudentRepository studentRepository)
      {
        this.studentRepository = studentRepository;
      }

并用作:

  public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
  {
     var students = from s in studentRepository.GetStudents()
                    select s;

完整的示例位于顶部的链接中。


那么你可以将一个模拟版本库传递给你的类:

// arrange
var mockedRepo = new Mock<IStudentRepository>();
// configure

// act
var controller = new StudentController(mockedRepo.Object);
// do stuff

// assert

迟了,但为什么不用mstest:

[TestMethod]
MyTestWithInternSqlConnection()
{
   using (ShimsContext.Create())
   {
      // simulate a connection
      ShimSqlConnection.AllInstances.Open = connection => { };
      string commandText;

      // shim-Mock all called methods
      ShimSqlCommand.AllInstances.ExecuteReader = command =>
      {
         commandText = command.CommandText;
         return new ShimSqlDataReader();
      };

      int readCount = 0;
      ShimSqlDataReader.AllInstances.Read = reader => readCount == 0;
      ShimSqlDataReader.AllInstances.GetSqlStringInt32 = (reader, i) =>
      {
         readCount++;
         return "testServer";
      };

      var theReadedString = AMethodUnderTestThatReadsFromDatabaseAString();
      Assert.IsTrue(theReadedString == "testServer");
   }
}

您需要添加对System.Data的引用,然后为其添加一个伪造。

https://msdn.microsoft.com/en-us/library/hh549175.aspx更好的是,如果你改变实现,你可以改变使用的读取层,但...

链接地址: http://www.djcxy.com/p/89873.html

上一篇: Moq and SqlConnection?

下一篇: Java Config for Spring Security with Vaadin