Как мне разбить это на модульные тесты? - PullRequest
2 голосов
/ 20 апреля 2009

У меня есть метод, который вызывается для объекта, чтобы выполнить некоторую бизнес-логику и добавить его в базу данных.

Объект является Транзакцией, и часть бизнес-логики требует поиска в базах данных связанных учетных записей и элементов истории в учетной записи.

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

Единственный способ, которым я могу придумать для тестирования этого в настоящее время, состоит в том, чтобы создать учетную запись и соответствующую историческую информацию, а затем построить транзакцию для каждого отдельного сценария и собрать информацию, записанную в БД для транзакции, и информацию передается, однако это похоже на слишком много испытаний в одном тесте. Каждый сценарий будет выполняться в отдельном модульном тесте, при этом конструкция теста будет реорганизована в отдельные методы, но фактический кусок кода, на который ориентирован тест, имеет длину более 500 строк.

Полагаю, этот вопрос больше относится к рефакторингу, чем к юнит-тестированию, но в этом случае они идут рука об руку.

Если у кого-нибудь есть совет (хороший или плохой), я буду рад его услышать.

EDIT:

Псевдокод:

Find account for transaction 
Do validation on transaction codes and values 
Update transaction with info from account 
Get related history from account Handle different transaction codes and values (6 different combinations, each with different logic) 
Update the transaction again with new account info (resulting from business logic) 
Send transaction to clients

Ответы [ 4 ]

4 голосов
/ 20 апреля 2009

Я был бы признателен, если бы у вас был какой-то псевдокод по этому вопросу, но просто следуя ему, я бы:

  • Создание интерфейсов для объектов доступа к данным, которые непосредственно обращаются к базе данных - таким образом, вы можете передать объект, который только притворяется (например, имитирует), что он обращается к базе данных. Этот объект затем будет возвращать результаты в соответствии с результатами, которые будет возвращать ваша база данных, без какого-либо вызова БД. Ваш объект также может имитировать такие сценарии, как откат данных до исходного состояния.
  • Извлекайте каждый «сценарий» в один метод каждый - это сущность единицы. Если ваш метод имеет длину 500 строк, то там должны быть смежные блоки, которые можно извлечь. При необходимости напишите юнит-тест для каждого.
  • Если ваш модульный тест слишком много тестирует, это, вероятно, означает, что ваш метод делает слишком много - Вы можете извлечь методы, идентифицируя различные тестируемые объекты, а затем помещая их в свои собственные методы. Промойте и повторяйте, пока вам не потребуется только один тест для каждого метода.
  • Транзакции, «переданные другим людям», звучат как запах кода - транзакция сама по себе должна быть только одной непрерывной единицей. Если вам нужны разные пользователи для завершения транзакции, вы делаете слишком много; вместо этого следите за состоянием ваших данных в БД, с точки зрения флагов и т. д., а не с точки зрения транзакции с БД.
1 голос
/ 20 апреля 2009

Отделение модулей от существующего унаследованного кода может быть чрезвычайно сложным и трудоемким. Проверьте Эффективная работа с устаревшим кодом для разнообразных опробованных и проверенных методов, чтобы сделать вещи более управляемыми.

0 голосов
/ 20 апреля 2009

Да, вы можете переписать текущий код, чтобы он мог быть протестирован модулем в соответствии с ко всем рекомендациям и передовым методам.

Однако, это может быть дорого, и Вы должны оценить стоимость и сравнить это против заработка ...

Выгода в том, что вы можете обнаружить проблему с кодом, а также, если все сделано правильно, снижение сложности в результате рефакторинга.

Оба фактора могут сэкономить время - в будущем.

Стоимость - это время и усилия, которые вы должны потратить на рефакторинг вашего кода, написание тестовых случаев, а также дополнительное время, которое вам, возможно, придется потратить в будущем поддерживать контрольные примеры и проверочный код - и это может привести к значительным затратам.

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

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

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

Если у вас старый код, разрешите тестирование в «черном ящике», разрешите зависимости между тестами и скомпилируйте последовательность тестов, которая устанавливает тестовые данные и манипулирует ими, и, по крайней мере, они автоматически тестируются, а не тестируются на 100%.

0 голосов
/ 20 апреля 2009

Это зависит от того, что вы хотели бы проверить. Вы хотите проверить транзакцию базы данных? Хотите проверить бизнес-транзакцию или что-то еще? Попробуйте использовать макеты для вещей, которые вы не хотели бы тестировать. С макетами вы можете сосредоточиться на определенных целях теста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...