Дразнящая DbProviderFactory - PullRequest
       39

Дразнящая DbProviderFactory

4 голосов
/ 16 сентября 2009

Я относительно новичок в модульном тестировании и совершенно не знаком с насмешками. У меня есть класс базы данных, который упаковывает фабрику DbProvider, для которой я хотел бы создать модульные тесты без подключения к базе данных.

Как бы я издевался над фабрикой DbProvider, чтобы я мог передать ее на тестирование своему классу? Нужно ли мне издеваться над DbConnection, DbCommand и т. Д.? Вот небольшой пример моего кода:

public Database(DbProviderFactory dbProviderFactory) {
    Provider = dbProviderFactory;
}

public int UpdateRecords(string sql, CommandType type, params DbParameter[] parameters) {
    int numberOfRecordsUpdated;

    using (var connection = CreateConnection()) {

        // Add ConnectionString
        connection.ConnectionString = ConnectionString;

        // Create command to hold the update statment
        using (var command = CreateCommand()) {
            try {
                command.Connection = connection;
                command.CommandType = type;
                command.CommandText = sql;

                // Add Parameters
                foreach (var parameter in parameters) {
                    command.Parameters.Add(parameter);
                }

                // Open Connection
                connection.Open();

                // Execute SQL
                numberOfRecordsUpdated = command.ExecuteNonQuery();
            } finally {
                command.Parameters.Clear();
            }
        }
    }

    return numberOfRecordsUpdated;
}

Ответы [ 3 ]

2 голосов
/ 17 сентября 2009

Интеграционное тестирование


Если вы заинтересованы (судя по вашим комментариям) в тестировании получения данных из базы данных, вы будете выполнять integration test.

Разница с unit testing для этих типов тестов заключается в том, что они выполняются реже - лучшие практики требуют, чтобы вы выполняли их перед переходом на контроль версий.

Причина в том, что они медленнее, и вы попадете в реальную базу данных (по крайней мере, в тестовую базу данных). При каждом запуске вам нужно будет стереть базу данных или не фиксировать изменения - вы, похоже, знаете, что делаете здесь, поэтому я оставлю вопрос о том, как вы справитесь с этим.

Mocking


Что касается тестирования вашей логики, которая использует базу данных - mocking и dependency injection - это путь.

Я использую Moq - это, пожалуй, самый простой фреймворк для использования. Это на самом деле не только для фиктивных объектов (несмотря на название), и вы можете создать с его помощью заглушек и подделок .

Псевдо-издевательство выглядит следующим образом (на примере БД):

  • Настроить макет
  • Скажите ему, что делать (ожидать) - например, вызов для сохранения.
  • Используйте SUT (тестируемая система)
  • Проверьте макет - в этом случае метод сохранения был вызван в вашей SUT.

Для получения дополнительной помощи - проверьте Google - есть несколько хороших ресурсов для модульного тестирования и насмешек.

1 голос
/ 17 сентября 2009

Я бы лично издевался над классом, который содержит функции доступа к данным более высокого уровня (например, UpdateRecords и т. Д.), И использовал бы эту насмешку для возврата предопределенных наборов данных.

Использование DbProvider и соответствующего DbCommand и т. Д. Является подробностью реализации уровня доступа к данным и не имеет отношения к функциональности более высокого уровня, использующей возвращаемые значения.

0 голосов
/ 16 сентября 2009

Классы доступа к данным предназначены для интеграции с БД. Рой Ошеров, например, считает эти классы исключением при юнит-тестировании. Мне тоже интересно, как проверить этот тип кода. +1 за вопрос.

IOW. Я не уверен, что желательно шутить над классами доступа к данным.

Что не нужно тестировать, когда дело доходит до модульного тестирования?

...