简体   繁体   中英

Unit Test fails on expected InvalidOperationException

I have written a unit test to test the some SQL operations in my application. Here is the test:

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

Method in question:

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;
}

This test fails however if I change the method to assert an equality on the return value and an InvalidOperationException and I am given the following message:

Message: Assert.AreEqual failed. Expected:System.InvalidOperationException: Operation is not valid due to the current state of the object. Actual:System.InvalidOperationException: ExecuteNonQuery: CommandText property has not been initialized

I've also duplicated the code to a separate project file to ensure the called method returns an InvalidOperationException, and it does. What am I missing?

Your method is returning an exception, not throwing an exception. The ExpectedExceptionAttribute expects your method to throw an unhandled exception. This line:

return ex;

returns the exception. Instead, just replace it with

throw;

or remove the try/catch entirely, since catching and doing nothing but rethrowing is the same as not catching it in the first place.

I'd also question if it makes sense for the function to return an Exception .

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

Is that really what you want, or should it return the result of executing the query? The function should return what you expect to receive, perhaps in this case a value from the query or a response indicating that it was executed. You don't have to return an exception. If one is thrown, it automatically gets bubbled up to the calling method. That method can handle it, or if it doesn't, it bubbles up to the next method, and so on.


That also explains the error you get if you change the test to assert equality. Whatever the return value you expect is, you're checking to see if it's equal to an Exception .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM