C# 如何对具有StreamReader和数据库访问权限的方法进行单元测试

C# 如何对具有StreamReader和数据库访问权限的方法进行单元测试,c#,sql-server,unit-testing,C#,Sql Server,Unit Testing,我以前从未做过单元测试。我想学怎么做。我想使用VisualStudio单元测试和moq 我的项目正在将数据从interbase传输到SQL Server。首先,我将interbase中的数据提取到一个纯文本文件中。布局为FieldName+部分空格(最多32个字符长度+字段值)。然后,我编写了一个逐行读取文本文件的方法;一旦到达下一条记录,它就会将当前记录插入SQL Server 因此,它涉及到流读取器和SQL数据库插入。对于流阅读器,我在互联网上阅读了一些帖子,并将流阅读器作为方法的参数传递给

我以前从未做过单元测试。我想学怎么做。我想使用VisualStudio单元测试和moq

我的项目正在将数据从interbase传输到SQL Server。首先,我将interbase中的数据提取到一个纯文本文件中。布局为FieldName+部分空格(最多32个字符长度+字段值)。然后,我编写了一个逐行读取文本文件的方法;一旦到达下一条记录,它就会将当前记录插入SQL Server

因此,它涉及到流读取器和SQL数据库插入。对于流阅读器,我在互联网上阅读了一些帖子,并将流阅读器作为方法的参数传递给它;但是在SQL Server部分,我不知道如何简化我的方法,以便可以对其进行测试

我真的需要你的帮助

public partial class TableTransfer
{
    #region declare vars
    public string FirstFldName = "";
    public string ErrorMsg = "";
    public List<MemoBlobTrio> MemoBlobs = null;
    public string SqlServerTableName = "";
    #endregion

    public bool DoTransfer(System.IO.StreamReader sr, Func<TransferShare, string, string, bool> TransferTable)
    {
        #region declare var
        bool DoInsert = true;
        TransferShare transferShare = null;
        string line = string.Empty;
        string blobLines = string.Empty;
        string fldName = string.Empty;
        string value = string.Empty;
        bool Is1stLine = true;
        bool isMemoFld = false;
        MemoBlobTrio memoBlobTrio = null;
        int idx = 0;
        #endregion

        try
        {
            using(sr)
            {
                transferShare = new TransferShare();
                ConnectSQLServer(transferShare);
                transferShare.StartInsert(SqlServerTableName);
                bool readNext = true;
                do
                {
                    try
                    {
                        if (readNext)
                            line = sr.ReadLine();

                        if ((line != null) && (line.Trim() != ""))
                        {
                            fldName = line.Length > 30 ? line.Substring(0, 31).TrimEnd() : "";

                            Is1stLine = fldName == FirstFldName;
                            if (Is1stLine)
                            {
                                if (DoInsert)
                                    EndInsert(transferShare, line);
                                else
                                    transferShare.ClearSQL();
                                DoInsert = true;
                            }

                            idx = 0;
                            isMemoFld = false;
                            while (idx < MemoBlobs.Count)
                            {
                                if (fldName == (MemoBlobs[idx] as MemoBlobTrio).fbFldName)
                                {
                                    memoBlobTrio = MemoBlobs[idx] as MemoBlobTrio;
                                    line = InsertMemoBlob(transferShare, sr, memoBlobTrio.ssFldName, fldName, memoBlobTrio.fbNextFldName);
                                    readNext = false;
                                    isMemoFld = true;
                                }
                                idx++;
                            }

                            if (!isMemoFld)
                            {
                                if (line.Length > 31)
                                    value = line.Remove(0, 31);
                                else
                                    value = "";
                                if (!TransferTable(transferShare, fldName, value))
                                    DoInsert = false;
                                readNext = true;
                            }
                        }
                    }
                    catch (Exception err)
                    {
                        HandleError(err, line);
                    }

                } while (line != null);
                if (DoInsert)
                    EndInsert(transferShare, line);
            }
        }
        finally
        {
            transferShare.SQLConn.Dispose();
        }
        return true;
    }

    private static void ConnectSQLServer(TransferShare transferShare)
    {
        TransferShare.SQLServerConnStr = "Data Source=" + Environment.MachineName + "\\SQLEXPRESS;Initial Catalog=MyDB;Integrated Security=True";
        transferShare.SQLConn.ConnectionString = TransferShare.SQLServerConnStr;
        transferShare.SQLConn.Open();
    }
}

public class TransferShare
{
    public void StartInsert(string TableName)
    {
        tableName = TableName;
    }

    public void EndInsert(TransferShare transferShare, string line)
    {
        SqlCommand Cmd = null;
        try
        {
            sqlInsFld = sqlInsFld.Remove(sqlInsFld.Length - 1);
            sqlInsValue = sqlInsValue.Remove(sqlInsValue.Length - 1);
            sqlInsFld = "Insert into " + tableName + " (" + sqlInsFld + ")";
            sqlInsValue = " Values (" + sqlInsValue + ")";

            Cmd = new SqlCommand(sqlInsFld + sqlInsValue, SQLConn);
            Cmd.ExecuteNonQuery();
        }
        catch (Exception err)
        {
            throw (new Exception(err.Message));
        }
        finally
        {
            sqlInsFld = "";
            sqlInsValue = "";
        }

    }
}
公共部分类表传输
{
#区域声明变量
公共字符串FirstFldName=“”;
公共字符串ErrorMsg=“”;
public List MemoBlobs=null;
公共字符串SqlServerTableName=“”;
#端区
公共布尔点传输(System.IO.StreamReader sr,Func TransferTable)
{
#区域声明变量
bool DoInsert=true;
TransferShare TransferShare=null;
string line=string.Empty;
string blobLines=string.Empty;
string fldName=string.Empty;
字符串值=string.Empty;
bool为1stline=true;
bool-isMemoFld=假;
MemoBlobTrio MemoBlobTrio=null;
int-idx=0;
#端区
尝试
{
使用(sr)
{
转让股份=新的转让股份();
连接SQLServer(transferShare);
transferShare.StartInsert(SqlServerTableName);
bool readNext=true;
做
{
尝试
{
如果(读下一步)
line=sr.ReadLine();
如果((line!=null)&&(line.Trim()!=“”)
{
fldName=line.Length>30?line.Substring(0,31).TrimEnd():“”;
Is1stLine=fldName==FirstFldName;
如果(Is1stLine)
{
如果(DoInsert)
EndInsert(转让股份,行);
其他的
transferShare.ClearSQL();
DoInsert=true;
}
idx=0;
isMemoFld=false;
while(idx31)
值=行。删除(0,31);
其他的
value=“”;
if(!可转让(转让股份、fldName、价值))
DoInsert=false;
readNext=true;
}
}
}
捕获(异常错误)
{
手柄错误(错误,线条);
}
}while(line!=null);
如果(DoInsert)
EndInsert(转让股份,行);
}
}
最后
{
transferShare.SQLConn.Dispose();
}
返回true;
}
私有静态无效连接SQLServer(TransferShare TransferShare)
{
TransferShare.SQLServerConnStr=“数据源=“+Environment.MachineName+”\\SQLEXPRESS;初始目录=MyDB;集成安全性=True”;
transferShare.SQLConn.ConnectionString=transferShare.SQLServerConnStr;
transferShare.SQLConn.Open();
}
}
公共类转让股份
{
public void StartInsert(字符串TableName)
{
tableName=tableName;
}
public void EndInsert(TransferShare TransferShare,字符串行)
{
SqlCommand Cmd=null;
尝试
{
sqlInsFld=sqlInsFld.Remove(sqlInsFld.Length-1);
sqlInsValue=sqlInsValue.Remove(sqlInsValue.Length-1);
sqlInsFld=“插入到“+tableName+”(“+sqlInsFld+”)中”;
sqlInsValue=“值(“+sqlInsValue+”);
Cmd=新的SqlCommand(sqlInsFld+sqlInsValue,SQLConn);
Cmd.ExecuteNonQuery();
}
捕获(异常错误)
{
抛出(新异常(错误消息));
}
最后
{
sqlInsFld=“”;
sqlInsValue=“”;
}
}
}

您的代码需要是可单元测试的。您的代码确实试图在每个函数中执行太多的操作。此代码与实现问题耦合得太紧密。这使得隔离测试(单元测试)非常困难。我建议重构上述代码,应用一些坚实的原则。这将大大提高这段代码的测试能力和可维护性。我知道这段代码有很大的问题,但我只是不知道如何改进它。有人能帮我吗?