热门使用Moq为SqlDataReader编写单元测试用例

时间:2016-08-04 20:53:06

标签: c# moq

我有以下方法,并希望通过DataReader编写用于映射结果的Unit测试用例。

public interface IIMGAdvancedSearchDBProvider
{
    clsGPAdvancedSearchResult GetSearchResult(clsIMGAdvancedImageSearchCriteria searchCriteria);
}

public class clsIMGAdvancedSearchSQLDBProvider : IIMGAdvancedSearchDBProvider
{
    public clsGLGJSearchResultItem GetSearchResult(clsIMGAdvancedImageSearchCriteria searchCriteria)
    {   
        using (var sqlConnection = DfxDbConnection)
        {
            using (var sqlCommand = sqlConnection.CreateCommand())
            {
                sqlCommand.Parameters.Add("@userKey", SqlDbType.UniqueIdentifier).Value = State.WebUserKey;
                sqlCommand.Parameters.Add("@SiteCode", SqlDbType.VarChar).Value = State.SiteCode;
                sqlCommand.Parameters.Add("@MaxRows", SqlDbType.Int).Value = searchCriteria.MaxRows;

                //Add required client, client group filter paramters
                AddClientAndClientGroupFilterParameters(searchCriteria, sqlCommand);

                sqlCommand.CommandType = CommandType.Text;
                sqlCommand.CommandText = GetCompleteSQLStatement(searchCriteria);

                var reader = sqlCommand.ExecuteReader();

                return alTransaction(reader);

                reader.Close();
            }
        }
        return null;
    }

    private clsGLGJSearchResultItem GetJournalTransaction(SqlDataReader reader)
    {
        return new clsGLGJSearchResultItem
        {

            ClientKey = DfxUtilities.GetGuidValueFromReader(reader, "ClientKey") ?? Guid.Empty,
            JournalId = DfxUtilities.GetLongValueFromReader(reader, "JournalID") ?? 0,
            AccountingDate = (DateTime)reader["Date"],

            JournalSource =
                (enumJournalSources)
                Enum.Parse(typeof(enumJournalSources), reader["Source"].ToString()),

            Description = DfxUtilities.GetStringValueFromReader(reader, "Description"),
            DebitAmount = DfxUtilities.GetDecimalValueFromReader(reader, "DebitAmount") ?? 0,
            CreditAmount = DfxUtilities.GetDecimalValueFromReader(reader, "CreditAmount") ?? 0,
            ClientCode = DfxUtilities.GetStringValueFromReader(reader, "ClientCode"),
            ClientName = DfxUtilities.GetStringValueFromReader(reader, "ClientName"),

            Images = GetImageItems(reader)
        };
    }
}

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

我认为您最好将数据抽象层(DAL)接口和类(如IIMGAdvancedSearchDBProviderclsIMGAdvancedSearchSQLDBProvider)视为集成测试而不是单元测试

换句话说,结合数据库模式,触发器,种子测试数据+ DAL实现类(包括对ExecuteReader的调用)的测试。 DAL应该很薄,并且排除业务逻辑。您通常会在数据库中设置/拆除测试数据以进行这些集成测试。您可能还希望为这些DAL集成测试类创建公共基类,以设置测试数据库连接以及某些SQL日志记录。可能还会使用边缘测试用例数据维护单独的测试数据库,或者在setup / teardowns中注入此数据。不要嘲笑这里。

然后,您可以通过模拟DAL接口IIMGAdvancedSearchDBProvider在使用DAL接口的组件/类中返回的值,单元测试上面的业务层类。我经常尝试首先完成DAL测试并捕获一些真实生产数据的快照。然后我从我的Mock DAL对象返回到业务层单元测试的情况。这样可以避免创建错过生产数据中真实数据边缘情况的模拟。

如果您正在使用NUnit,请考虑使用他们的TestCasePairwiseCombinatorial属性为您的业务层对象生成测试用例(而不是模拟它们)。您也可以找到我的ShouldBe包装库。

BTW ...您的cls类前缀命名约定是非标准的。