负责对数据库进行调用的服务:
public class DbClient : IDbClient
{
private readonly IOptions<DbSettings> _dbSettings;
public DbClient(IOptions<DbSettings> dbSettings)
{
_dbSettings = dbSettings;
}
public List<EmployeeDataModel> GetEmployees()
{
using (SqlConnection connection = new SqlConnection(_dbSettings.Value.ConnectionString))
{
connection.Open();
return connection.GetAll<EmployeeDataModel>().ToList();
}
}
public void InsertEmployee(EmployeeDataModel employee)
{
using (SqlConnection connection = new SqlConnection(_dbSettings.Value.ConnectionString))
{
connection.Open();
connection.Insert(employee);
}
}
public void DeleteEmployee(int id)
{
using (SqlConnection connection = new SqlConnection(_dbSettings.Value.ConnectionString))
{
connection.Open();
connection.Delete( new EmployeeDataModel() {Id = id });
}
}
public void EditEmployee(EmployeeDataModel employee)
{
using (SqlConnection connection = new SqlConnection(_dbSettings.Value.ConnectionString))
{
connection.Open();
connection.Update(employee);
}
}
}
它只是执行简单的CRUD操作。
问题:此服务无法轻松进行集成测试。原因?它在每个方法内创建SQL连接(这是第一个问题,我只想在创建问题的地方放一个地方),并且无法使用事务范围模拟此SQL连接(以回滚集成测试)。在这种情况下如何应用工厂模式?
将IDbConnection注入到您的构造函数中,并在创建服务时让工厂传递该连接。这是一个例子:
public class SqlService { private IDbConnection _connection; public SqlService(IDbConnection connection) { _connection = connection; } public void DoSql() { using (_connection) { _connection.Open(); // Do sql // Also assuming that .GetAll is an IDbConnection extension from your ORM. } } }
public class TestFactory { private bool _isTestMode; public TestFactory(bool isTestMode) { _isTestMode = isTestMode; } public SqlService GetSqlService() { if (_isTestMode) { var connectionToMockData = // mock data connection return new SqlService(connectionToMockData); } else { var sqlConnection = new SqlConnection(_dbSettings.Value.ConnectionString); return new SqlService(sqlConnection); } } }