【发布时间】:2019-09-16 11:21:22
【问题描述】:
我有一个被多次调用的通用方法(项目中大约有 30-35 个引用)。这种方法基本上是从数据库中获取数据到数据表中。
以下是可测试的代码:
public class MyApp
{
private readonly IDataProvider _dbProvider;
public MyApp(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
}
public void Process()
{
string query = "something";
Helper h = new Helper(_dbProvider);
// This method will be called in the Process method several times
var data = h.GetData(query);
}
}
public interface IDataProvider
{
IDbConnection CreateConnection(string connectionString);
DataTable FillDatatableFromAdapter(IDbCommand command);
}
public class DataProvider : IDataProvider
{
public IDbConnection CreateConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
public DataTable FillDatatableFromAdapter(IDbCommand command)
{
DataSet dataSet = new DataSet();
SqlCommand sqlCommand = command as SqlCommand;
using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
{
sqlDataAdapter.Fill(dataSet);
}
if (dataSet.Tables.Count == 0)
return null;
return dataSet.Tables[0];
}
}
public class Helper
{
private readonly IDataProvider _dbProvider;
public Helper(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
}
public DataTable GetData(string query)
{
DataTable table = new DataTable();
using (IDbConnection connection =
_databaseProvider.CreateConnection(_connectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = query;
command.Connection = connection;
table = _dbProvider.FillDatatableFromAdapter(command);
}
}
return table;
}
}
我已经模拟了 DB 类以不从单元测试中命中 DB。 以下是测试用例代码:
[TestMethod]
public void TestMyApp()
{
Mock<IDbCommand> mockDbCommand = new Mock<IDbCommand>();
Mock<IDbConnection> mockDbConnection = new Mock<IDbConnection>();
Mock<IDataProvider> mockDatabaseProvider = new Mock<IDataProvider();
mockDbConnection.Setup(m => m.CreateCommand()).Returns(mockDbCommand.Object);
mockDatabaseProvider.Setup(m => m.CreateConnection(It.IsAny<string>())).Returns(mockDbConnection.Object);
DataTable table = new DataTable();
mockDatabaseProvider.SetupSequence(mock => mock.FillDatatableFromAdapter(It.IsAny<IDbCommand>()))
.Returns(dataTable);
MyApp app = new MyApp(mockDatabaseProvider.Object);
app.Process();
// And then after that I am testing some data.
}
我将多次调用 GetData() 方法,因此 FillDatatableFromAdapter 也将被多次调用。在上面的测试用例中,我模拟了 FillDatatableFromAdapter 方法,并返回了一些假数据表以供进一步测试。 我知道 Moq 中的 SetupSequence 方法,每次调用该方法时,我都可以使用该方法从模拟方法返回多个数据表。
我想要一个建议是该方法正确,因为那样我将不得不创建许多数据表,这些数据表将从使用 SetupSequence 的模拟方法返回?还是有其他更好的方法?
有什么帮助吗??
【问题讨论】:
-
它按原样工作吗?
-
是的,它正在工作,但是我正在创建多个要返回的数据表。
-
你的
Helper类不应该也实现一个接口吗?因为这是您的MyApp类的主要依赖项(Helper 包装了IDataProvider)。然后你应该在你的测试中模拟Helper类,因为你现在想测试MyApp类的逻辑
标签: c# .net unit-testing mocking moq