Модульное тестирование и хранимые процедуры - PullRequest
3 голосов
/ 14 июля 2009

Как вы тестируете свой код, использующий вызовы хранимых процедур?

В своих приложениях я использую много модульного тестирования (NUnit). Для моего DAL я использую DevExpress XPO ORM. Одним из преимуществ XPO является то, что он позволяет вам использовать хранение данных в памяти. Это позволяет мне устанавливать тестовые данные в моих тестовых приборах без внешней зависимости от базы данных.

Затем пришла оптимизация! Для некоторых частей наших приложений нам пришлось прибегнуть к замене кода, который манипулирует данными через наш ORM, на вызов хранимых процедур T-SQL. Это, конечно, сломало наш хороший тестируемый код, добавив новую внешнюю зависимость. Мы не можем просто «макетировать» вызов хранимой процедуры, потому что мы тестировали побочные эффекты манипулирования данными.

У меня уже есть планы в конечном итоге заменить использование XPO на LINQ to SQL; LINQ to SQL, кажется, позволяет мне лучше запрашивать возможности, чем XPO, устраняя необходимость в некоторых хранимых процедурах. Я надеюсь, что если я перейду на LINQ to SQL, я смогу, чтобы мои модульные тесты использовали LINQ to Objects, чтобы избежать зависимости от базы данных. Однако я сомневаюсь, что все spocs могут быть заменены LINQ to SQL.

Должен ли я:

  • прикуси и поменяй некоторые из моих тестовых приспособлений, чтобы они создавали базы данных SQL Server,
  • создавать модульные тесты базы данных вместо тестирования кода,
  • или пропустить тестирование этих изолированных инцидентов, потому что они того не стоят?

Я также хотел бы услышать о ваших альтернативных настройках, где хранимые процедуры мирно сосуществуют с вашим тестируемым кодом.

1 Ответ

2 голосов
/ 14 июля 2009

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

class foo:

    prop1 = 5

    def method1(listOfData):
        for item in listOfData:
            dbobj.callprocedure('someprocedure',item+prop1)

Может быть выполнен рефакторинг для инкапсуляции вызова удаленной системы в собственный метод:

class foo:
    prop1 = 5
    def method1(listOfData):
        for item in listOfData:
            someprocedure(item+prop1)

    def someprocedure(value):
        dbobj.callprocedure('someprocedure',value)

Теперь, когда вы пишете свои модульные тесты, смоделируйте метод класса someprocedure (), чтобы он фактически не выполнял вызов базы данных. Затем создайте отдельный набор интеграционных тестов, для которых требуется настроенная база данных, которая вызывает актуальную версию someprocedure () и затем проверяет, что база данных находится в правильном состоянии.

...