1

I'm writing unit tests and I want to simulate the scenario where a DB2Exception gets thrown.

The problem is that it has no public constructors, so I can't create it, and most unit-testing frameworks (I use Rhino Mocks with nunit) also can't create stubs for them.

Am I stuck with not being able to test this interaction?

(Details: this is the DB2Exception defined in IBM.Data.DB2.dll - version 8.1.2.1)

Jeff B
  • 8,572
  • 17
  • 61
  • 140
  • Are you using NUnit as your test runner? – akousmata Jan 25 '13 at 23:27
  • @akousmata Yes, I am. Edited :) – Jeff B Jan 25 '13 at 23:34
  • Deleted my previous post after I realized it wasn't that helpful, but one approach is to use a wrapper class just for executing your query. Are you trying to test the behavior of your catch clause or something along those lines? – akousmata Jan 25 '13 at 23:59
  • Yup, trying to test a catch clause. I could use a wrapper class, but I'd also need to create a wrapper exceptions as well, which is unfortunate. – Jeff B Jan 27 '13 at 15:36
  • Yeah, that's the only approach I'm aware of, which is unfortunate. There must be something hidden in DB2Exception they don't want you to get your hands on cause otherwise, they wouldn't have made it sealed. – akousmata Jan 28 '13 at 14:55

2 Answers2

2

EDIT My previous post wasn't helpful at all, here's my second attempt. While you may still want to perform some elements of mocking in this, without your code to look at, I don't know which elements of this approach will work and which ones won't. Anyways, here's an approach I take when trying to test catch blocks or exceptions in general:

public class A
{
    public void ExecuteDB2Query(string query, DB2Connection connection)
    {
        try
        {
            // Code for executing the DB2 query
        }
        catch(DB2Exception ex)
        {
            // Catch block you are trying to test
        }
    }

    // Actual method
    public void MyMethod()
    {
        var query = "Select * FROM TableInApplication";
        var connection = new DB2Connection("DATABASE=GOODDB");
        ExecuteDB2Query(query, connection);
    }
}

[Test]
public void MyMethod_CallsExecutDB2Query()
{
    // Test that MyMethod is calling ExecuteDB2Query   
}

// Intentionally pass it bad data to test your catch block
// under the notion that the code that executes in the application 
// will be using the same method and thus the same catch block
[Test]
public void ExecuteDB2Query_Handles_Exception()
{
    var queryString = "Select* FROM NonExistentTable";
    var connection = new DB2Connection("DATABASE=BADDB");
    var aClass = new A();
   Assert.Throws<DB2Exception>(() => aClass.ExecuteDB2Query(queryString, connection));
}

This isn't the most elegant way to handle this but if you can't stub out the exception then splitting up the responsibilities of the code and testing each piece separately by triggering the exception is the next best thing I guess.

akousmata
  • 1,005
  • 14
  • 34
  • I had thought about this method... unfortunately I'm wanting to test for specific errors codes (deadlock/rollback) where it might be valid to try again ;) – Jeff B Jan 27 '13 at 15:38
1

I was hoping DB2Exception had some derived classes, but alas - no, it's sealed. Here's the class description.

Since DB2Exceptions are obviously thrown by someone, there's probably an internal constructor. You'll have to resort to reflection to use it. There was once a .NET Reflector that analyzed MSIL and produced C# code, but now it costs money. You can find some alternatives here.

Community
  • 1
  • 1
zmbq
  • 38,013
  • 14
  • 101
  • 171