基于MySql查询的C#UnitTesting方法
我尝试在我的应用程序的数据库层中对一个方法进行单元测试。在我的测试中,我计划编写mock来避免与MySQL的实时连接。 我将写下我的代码的简化版本来说明。让我们从单元测试开始:基于MySql查询的C#UnitTesting方法,c#,mysql,unit-testing,C#,Mysql,Unit Testing,我尝试在我的应用程序的数据库层中对一个方法进行单元测试。在我的测试中,我计划编写mock来避免与MySQL的实时连接。 我将写下我的代码的简化版本来说明。让我们从单元测试开始: [TestMethod()] public void TestMethod1() { DataBaseInterface database = new DataBaseInterface(); // this is the class which has the method I want to unit test
[TestMethod()]
public void TestMethod1()
{
DataBaseInterface database = new DataBaseInterface(); // this is the class which has the method I want to unit test
DataSet ds = new DataSet();
ds.Tables.Add(new DataTable("signals"));
ds.Tables[0].Columns.Add(new DataColumn("ID"));
ds.Tables[0].Columns.Add(new DataColumn("Content"));
DataRow row = ds.Tables[0].NewRow();
row["ID"] = "1";
row["Content"] = "Foo";
ds.Tables[0].Rows.Add(row);
MockDataBaseConnection db = new MockDataBaseConnection();
string result = database.GetContent(1); // this is the method I want to unit test
}
我想要进行单元测试的方法如下所示:
public class DatabaseInterface
{
private MySqlConnectionAdapter _sqlConn;
public string GetContent(int i)
{
MySqlCommand command = _sqlConn.CreateCommand();
command.CommandText = String.Format("");
_sqlConn.Open();
MySqlDataReader reader = command.ExecuteReader();
/// more code here
}
public class MySqlConnectionAdapter
{
public MySqlConnection _sqlConn;
public MySqlConnectionAdapter()
{
}
public MySqlConnectionAdapter(string con)
{
_sqlConn = new MySqlConnection(con);
}
public event MySqlInfoMessageEventHandler InfoMessage
{
add
{
_sqlConn.InfoMessage += value;
}
remove
{
_sqlConn.InfoMessage -= value;
}
}
public virtual event StateChangeEventHandler StateChange
{
add
{
_sqlConn.StateChange += value;
}
remove
{
_sqlConn.StateChange -= value;
}
}
public virtual void Open()
{
_sqlConn.Open();
}
public void Close()
{
_sqlConn.Close();
}
public string ServerVersion
{
get
{
return _sqlConn.ServerVersion;
}
}
protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
return _sqlConn.BeginTransaction(isolationLevel);
}
public void ChangeDatabase(string databaseName)
{
_sqlConn.ChangeDatabase(databaseName);
}
public string ConnectionString
{
get
{
return _sqlConn.ConnectionString;
}
set
{
_sqlConn.ConnectionString = value;
}
}
public virtual MySqlCommand CreateCommand()
{
return _sqlConn.CreateCommand();
}
public string DataSource
{
get
{
return _sqlConn.DataSource;
}
}
public string Database
{
get
{
return _sqlConn.Database;
}
}
public ConnectionState State
{
get
{
return _sqlConn.State;
}
}
}
public class MockDataBaseConnection : MySqlConnectionAdapter
{
public DataSet ds;
public new MockMySqlCommand CreateCommand()
{
return new MockMySqlCommand(ds);
}
}
public class MockMySqlCommand
{
private DataSet _ds;
public MockMySqlReader ExcecuteReader()
{
return new MockMySqlReader(_ds);
}
public MockMySqlCommand(DataSet ds)
{
_ds = ds;
}
}
public class MockMySqlReader
{
public DataSet _ds;
private int currRow = 0;
public MockMySqlReader(DataSet ds)
{
_ds = ds;
}
public bool Read()
{
if (currRow < _ds.Tables[0].Rows.Count)
{
currRow++;
return true;
}
else return false;
}
public object GetValue(int i)
{
return _ds.Tables[0].Rows[currRow][i];
}
}
为了防止在我的unitest中使用实际的数据库连接,我编写了一些模型,问题就在这里。
实体模型如下所示:
public class DatabaseInterface
{
private MySqlConnectionAdapter _sqlConn;
public string GetContent(int i)
{
MySqlCommand command = _sqlConn.CreateCommand();
command.CommandText = String.Format("");
_sqlConn.Open();
MySqlDataReader reader = command.ExecuteReader();
/// more code here
}
public class MySqlConnectionAdapter
{
public MySqlConnection _sqlConn;
public MySqlConnectionAdapter()
{
}
public MySqlConnectionAdapter(string con)
{
_sqlConn = new MySqlConnection(con);
}
public event MySqlInfoMessageEventHandler InfoMessage
{
add
{
_sqlConn.InfoMessage += value;
}
remove
{
_sqlConn.InfoMessage -= value;
}
}
public virtual event StateChangeEventHandler StateChange
{
add
{
_sqlConn.StateChange += value;
}
remove
{
_sqlConn.StateChange -= value;
}
}
public virtual void Open()
{
_sqlConn.Open();
}
public void Close()
{
_sqlConn.Close();
}
public string ServerVersion
{
get
{
return _sqlConn.ServerVersion;
}
}
protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
return _sqlConn.BeginTransaction(isolationLevel);
}
public void ChangeDatabase(string databaseName)
{
_sqlConn.ChangeDatabase(databaseName);
}
public string ConnectionString
{
get
{
return _sqlConn.ConnectionString;
}
set
{
_sqlConn.ConnectionString = value;
}
}
public virtual MySqlCommand CreateCommand()
{
return _sqlConn.CreateCommand();
}
public string DataSource
{
get
{
return _sqlConn.DataSource;
}
}
public string Database
{
get
{
return _sqlConn.Database;
}
}
public ConnectionState State
{
get
{
return _sqlConn.State;
}
}
}
public class MockDataBaseConnection : MySqlConnectionAdapter
{
public DataSet ds;
public new MockMySqlCommand CreateCommand()
{
return new MockMySqlCommand(ds);
}
}
public class MockMySqlCommand
{
private DataSet _ds;
public MockMySqlReader ExcecuteReader()
{
return new MockMySqlReader(_ds);
}
public MockMySqlCommand(DataSet ds)
{
_ds = ds;
}
}
public class MockMySqlReader
{
public DataSet _ds;
private int currRow = 0;
public MockMySqlReader(DataSet ds)
{
_ds = ds;
}
public bool Read()
{
if (currRow < _ds.Tables[0].Rows.Count)
{
currRow++;
return true;
}
else return false;
}
public object GetValue(int i)
{
return _ds.Tables[0].Rows[currRow][i];
}
}
公共类MySqlConnectionAdapter
{
公共MySqlConnection\u sqlConn;
公共MySqlConnectionAdapter()
{
}
公共MySqlConnectionAdapter(字符串con)
{
_sqlConn=新的MySqlConnection(con);
}
公共事件MySqlInfoMessageEventHandler InfoMessage
{
添加
{
_sqlConn.InfoMessage+=值;
}
去除
{
_sqlConn.InfoMessage-=值;
}
}
公共虚拟事件StateChangeEventHandler StateChange
{
添加
{
_sqlConn.StateChange+=值;
}
去除
{
_sqlConn.StateChange-=值;
}
}
公共虚拟空间打开()
{
_sqlConn.Open();
}
公众假期结束()
{
_sqlConn.Close();
}
公共字符串服务器版本
{
得到
{
返回_sqlConn.ServerVersion;
}
}
受保护的DbTransaction BeginDbTransaction(IsolationLevel IsolationLevel)
{
返回_sqlConn.BeginTransaction(隔离级别);
}
公共void ChangeDatabase(字符串databaseName)
{
_sqlConn.ChangeDatabase(databaseName);
}
公共字符串连接字符串
{
得到
{
返回_sqlConn.ConnectionString;
}
设置
{
_sqlConn.ConnectionString=值;
}
}
公共虚拟MySqlCommand CreateCommand()
{
返回_sqlConn.CreateCommand();
}
公共字符串数据源
{
得到
{
返回_sqlConn.DataSource;
}
}
公共字符串数据库
{
得到
{
返回_sqlConn.Database;
}
}
公共连接州
{
得到
{
返回_sqlConn.State;
}
}
}
公共类MockDataBaseConnection:MySqlConnectionAdapter
{
公共数据集ds;
公共新MockMySqlCommand CreateCommand()
{
返回新的MockMySqlCommand(ds);
}
}
公共类MockMySqlCommand
{
私有数据集;
public MockMySqlReader executereader()
{
返回新的MockMySqlReader(_-ds);
}
公共MockMySqlCommand(数据集ds)
{
_ds=ds;
}
}
公共类MockMySqlReader
{
公共数据集;
私有int currow=0;
公共MockMySqlReader(数据集ds)
{
_ds=ds;
}
公共bool Read()
{
如果(当前行<_ds.Tables[0].Rows.Count)
{
currRow++;
返回true;
}
否则返回false;
}
公共对象GetValue(int i)
{
返回_ds.Tables[0]。行[currRow][i];
}
}
当执行行_sqlConn.CreateCommand()时,它会抛出和执行选项。为什么呢?
单元测试方法中的_sqlconnfiels是一个MockDataBaseConnection对象,我希望它返回一个MockMySqlCommand对象
MySQL dll的密封分类让我头疼。有人能解释一下我如何修复代码,或者展示一个简单的方法单元测试示例吗
它在不实际查询数据库的情况下查询数据库。就像vulkanino建议的那样,我认为设置本地数据库实例并直接在其上运行测试要容易得多
我也遇到过同样的情况,并且开发了这个项目,它只需设置一个本地运行的MySql测试服务器实例,而不必关心服务器管理:查询本地测试数据库不是更容易吗?是的,我想是这样。我还没有完成这一点。我无法找到解决方案,因此我正在使用与我计划在生产中使用的数据库相同(或类似)的数据库进行测试。