【问题标题】:How to test C# method that uses SQL Connection and stored procedure如何测试使用 SQL 连接和存储过程的 C# 方法
【发布时间】:2022-01-14 13:41:11
【问题描述】:

我目前面临一个大问题,我需要在 nUnit 中测试使用 SQL Server 连接和存储过程的方法。出于某种原因,当我尝试模拟存储库并初始化依赖项时,该方法总是崩溃。

这是我的方法:

public int RunStoredProcedure()
{
        List<string> myList = new List<string>();
        string connetionString = null;

        SqlConnection connection;
        SqlDataAdapter adapter;

        SqlCommand command = new SqlCommand();
        SqlParameter param;

        DataSet ds = new DataSet();

        int i = 0;

        connetionString = _myConnectionRepo.ConnectionString;
        connection = new SqlConnection(connetionString);

        connection.Open();
        command.Connection = connection;
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "SPCOUNTRY";

        param = new SqlParameter("@COUNTRY", "Germany");
        param.Direction = ParameterDirection.Input;
        param.DbType = DbType.String;
        command.Parameters.Add(param);

        adapter = new SqlDataAdapter(command);
        adapter.Fill(ds);

        for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
        {
            myList.Add(ds.Tables[0].Rows[i][0].ToString());
        }

        connection.Close();
}

而单元测试是:

[Test]
public void Should_Return_String_list()
{
        _repository.Setup(r => r.RunStoredProcedure()).Returns(new List<string>
        {
            "string1",
            "string2",
            "string3"
        });
        _cnxStringService
             .SetUp(x => x.GetConnectionString)
             .Returns("MockConnectionString");
        var result = _repository.RunStoredProcedure();

        Assert.That(result, It.IsNotNull);
}

当我运行项目时它运行完美,它正确返回值但单元测试说连接字符串应该为空,我试图传递一个简单的字符串但它说格式不正确,我也试过了使用随机连接字符串,它说没有连接,但是如果我传递本地连接字符串,它可以工作,但是当我推送我的更改时,它会崩溃。

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

提前致谢。

【问题讨论】:

  • 您设置了返回字符串列表的r.RunStoredProcedure(),但您发布的方法返回一个整数。你在嘲笑错误的事情吗?另外,您在方法中对连接字符串进行硬编码?
  • 您不会模拟您要测试的东西,而是要模拟您要测试的东西的依赖项
  • 请显示minimal reproducible example。第一个代码块RunStoredProcedure 没有return 并且无法编译。我们不知道测试方法中的变量发生了什么。 _videoService 类型是什么样的,你正在测试的实际东西是什么?你在使用接口吗?
  • 是的,我用的是接口和repositories,基本上是单元测试的问题,因为调试后进入方法,连接字符串说是空的,就崩溃了。跨度>
  • 当你模拟一个方法时,它不会运行它,所以如果它抱怨连接字符串,那么你就没有调用模拟。在您的实际代码库中,_repository 使用的是什么类型?将你的模拟注入那个东西并调用那个使用repository的方法。

标签: c# sql-server unit-testing nunit


【解决方案1】:

我自己解决了这个问题,解决方案如下,为了避免在单元测试(nUnit)中出现空引用,我们必须做的是创建两个单独的方法,一个从引用项目中检索连接字符串,另一个拆分该连接字符串的值。

private static string ReturnConnectionString(IEnumerable<JToken> jTokenValues)
    {
        var cnxString = string.Empty;
        for (int i = 0; i < jTokenValues.Count(); i++)
        {
            var str1 = jTokenValues.ElementAt(i);

            foreach (JProperty attributeProperty in str1)
            {
                if (attributeProperty.Name == "SqlConnectionString")
                {
                    var attribute = str1[attributeProperty.Name];
                    cnxString = attribute.ToString();
                }
            }
        }

        return cnxString;
    }

    private static IEnumerable<JToken> ConfigureEnvironmentVariablesFromLocalSettings()
    {
        var path = Path.GetDirectoryName(typeof(DimAccountRepository)
            .Assembly.Location); var json =
                File.ReadAllText(Path.Join(path, "local.settings.json"));
        var parsed = Newtonsoft.Json.Linq.JObject.Parse(json).Values();

        return parsed;
    }

因此,我们可以初始化服务并传递连接字符串并避免空引用。

【讨论】:

    猜你喜欢
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多