Michael Wheeler
Michael Wheeler

Reputation: 2507

How can I write an automated test for exception handling

I have a lot of the following type of code (each gets data from different tables).

public class TableOneDAO
{
    public TableOneDAO(IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
        _log = LogFacade.GetLog();
        _tableOneRowMapper = new TableOneRowMapper();
    }

    public IList<TableOneRecord> FindAll()
    {
        try
        {
            using (IDbCommand cmd = _dbConnection.CreateCommand())
            {
                cmd.CommandText = TableOneSql.FindAllSql();

                return _tableOneRowMapper.GetObjectList(cmd.ExecuteReader());
            }
        }
        catch (Exception exception)
        {
            _log.Error(exception.Message, exception);

            throw;
        }
    }

    private readonly IDbConnection _dbConnection;
    private readonly TableOneRowMapper_tableOneRowMapper;
    private readonly ILog _log;
}

_tableOneRowMapper.GetObjectList(cmd.ExecuteReader()) gets the the data from the database and maps it to a List. We have had past issues of records causing issues in the mapping and now want to log those right away and then trow them to the calling application. I have tests for everything but the exception handling. I must keep the generic exception handling in place.

I am using or have the following available to use:

MY QUESTIONS:

Upvotes: 1

Views: 1161

Answers (2)

AlanT
AlanT

Reputation: 3663

•How can I create automated tests (unit or integration) for the exception handling?

NUnit has an ExpectedException attribute (http://www.nunit.org/index.php?p=exception&r=2.4) which verifies that an exception has been thrown.

You will also want to verify that the exception has been logged. Can LogFacade.GetLog() return a mock log?

•Are there any other ways to do this without injecting it?

It depends upon your definition of 'injecting'.

In the general sense of injecting - using something not created in the class - you do need to inject the mapper, otherwise, as @sll says, it's not a unit test.

If you are worried about changing the ctor for TableOneDAO, you can use a factory to create the mapper instead of creating it within the DAO. In your tests you can register the mock mapper with the factory.

Other

If you are going to be doing this a lot (creating and testing lots of table DAOs) I would create a base TableDAO class and derive all the others from it. The derived classes only need to provide the mapper and sql string.

Doing it this way, the exception handling only needs to be unit tested once; for the base class.

hth,

Alan.

Upvotes: 1

sll
sll

Reputation: 62544

? How can I create automated tests (unit or integration) for the exception handling?

// ensure that a given code block throws specific exception
Assert.Throws<ExceptionType>(() => { code block to execute });

// ensure that a given code block DOES NOT throw specific exception
Assert.DoesNotThrow(() => { code block to execute });

? Do I need to inject the TableOneRowMapper and mock it so it throws an exception when called?

  • Unti test - yes, since it is a dependency you should inject it
  • Integration test - no

? Are there any other ways to do this without injecting it?

No, otherwise it would be an integration test rather unit test

? Do I not worry about testing the exception handling?

???

Upvotes: 3

Related Questions