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