单元测试在预期的InvalidOperationException上失败

时间:2019-04-05 14:54:51

标签: c# unit-testing

我写了一个单元测试来测试我的应用程序中的一些SQL操作。这是测试:

[TestMethod]
[ExpectedExceptionAttribute(typeof(InvalidOperationException))]
public void ExecuteSQL_CommandInvalidSyntax_ThrowsException()
{
    var result = TestSqlHandler.ExecuteSQL(new List<int>
    {
        1, 2, 3, 4
    }, "Invalid command text");
}

有问题的方法:

public static Exception ExecuteSQL(List<int> walletList, string command)
{
    try
    {
        using (var conn = new SqlConnection("Omitted"))
        {
            if (conn.State == ConnectionState.Open)
                conn.Close();


            string sql = command;
            using (var cmd = new SqlCommand(sql, conn))
            {
                conn.Open();
                foreach (int row in walletList)
                {
                    cmd.Parameters.AddWithValue("@par1", row.ToString());
                    cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                }
                conn.Close();
            }
        }
    }
    catch (Exception ex)
    {
        return ex;
    }
    return null;
}

但是,如果我更改方法以在返回值和InvalidOperationException上声明相等,则此测试失败,并且得到以下消息:

  

消息:Assert.AreEqual失败。 Expected:System.InvalidOperationException:由于对象的当前状态,操作无效。   Actual:System.InvalidOperationException:ExecuteNonQuery:CommandText属性尚未初始化

我还将代码复制到一个单独的项目文件中,以确保被调用的方法返回InvalidOperationException,并且确实如此。我想念什么?

1 个答案:

答案 0 :(得分:1)

您的方法是返回一个异常,而不是抛出一个异常。 ExpectedExceptionAttribute希望您的方法抛出未处理的异常。这行:

return ex;

返回异常。相反,只需将其替换为

throw;

或完全删除try / catch,因为除了重新抛出外,仅捕获和执行其他操作与一开始就没有捕获相同。

我还要问函数返回Exception是否有意义。

public static Exception ExecuteSQL(List<int> walletList, string command)

这真的是您想要的,还是应该返回执行查询的结果?该函数应返回您期望要接收的内容,在这种情况下,可能是查询的值或表明已执行该值的响应。您不必返回异常。如果抛出一个,它将自动冒泡至调用方法。该方法可以处理它,否则,它会冒出气泡直到下一个方法,依此类推。


这也解释了如果您将测试更改为断言相等性会遇到的错误。无论您期望的返回值是多少,您都在检查它是否等于Exception