views:

90

answers:

2

I have a test that passes if I am not debugging the test:

Snippet:

using (var reader = dbUtility.ExecuteReader(cmd))
{
    if (reader != null)
    {
        while (reader.Read())
        {

In my Arrange step, I set up a stub that will return one row's worth of information. The part that breaks during debug only is the reader.Read() call. The debugger appears to eat the read() call and the evaluates to false, never entering the scope of the while{} block.

So what is happening here? Is there a way to refactor this?

By request from Skeet:

Full working test:

[Test]
public void StateValueTest()
{
    // Borrowed from Phil Haack 
    StubResultSet resultSet
       = new StubResultSet("stateid", "stateabbr", "statename", "regionid");
    resultSet.AddRow(1, "CA", "California", 0);
    StubDataReader mockReader = new StubDataReader(resultSet);

    // Using Kzu's Moq framework <3
    var mockDbUtil = new Mock<IDbUtility>();
    mockDbUtil.Setup(conn => conn.GetSqlConnection());
    mockDbUtil.Setup(cmd => cmd.CreateSqlProcCommand(It.Is<string>(procName => procName == "spGetStates"), It.IsAny<SqlConnection>()));
    mockDbUtil.Setup(exec => exec.ExecuteReader(It.IsAny<SqlCommand>())).Returns(mockReader);

    State.dbUtility = mockDbUtil.Object;

    List<State> states = State.States;

    mockDbUtil.VerifyAll();

    Assert.Less(0, states.Count);
}

Code under Test:

public static List<State> States
{
    get
    {
        List<State> results = new List<State>();

        using (var conn = dbUtility.GetSqlConnection())
        {
            using (var cmd = dbUtility.CreateSqlProcCommand("spGetStates", conn))
            {
                using (var reader = dbUtility.ExecuteReader(cmd))
                {
                    if (reader != null)
                    {
                        while (reader.Read())
                        {
                            State state = new State
                            {
                                stateId = ConversionUtility.ConvertInt(reader["stateid"]),
                                stateAbbr = ConversionUtility.ConvertString(reader["stateabbr"]),
                                stateName = ConversionUtility.ConvertString(reader["statename"]),
                                regionId = ConversionUtility.ConvertInt(reader["regionid"])
                            };
                            results.Add(state);
                        }
                    }
                }
            }
        }

        return results;
    }
}
+1  A: 

My guess is that one of the properties in your stub is executing in the debugger, and eating the data.

Make sure all your property getters are side-effect free and all should be well.

If that isn't it, please post some code - ideally a short but complete program that reproduces the problem.

Jon Skeet
Will check for side effects from properties, thanks Jon.
Jason Slocomb
A: 

Some speculation:

When running under the debugger is the sql server debugging mode included? Uou can alter this on launching the debugger if using attach. I find this can sometimes play hell with my sql sessions (not to mention slowing them down).

Alternatively is that your mocking tools aren't liking being run in a multi threaded manner? What happens if you try just that one test on it's own with/without the debugger?

ShuggyCoUk
Thanks Shuggy. SQL Debugging is not enabled, however, this is an existing integration test I am attempting to coax into a unit test by mocking responses along all of the dbutility vectors. No DB calls here at all. The mocking tools might be the culprit. My next step is to eliminate the mocking and see if the original test behaved similarly.
Jason Slocomb