Как вы тестируете юзер-загруженные свойства Subsonic? - PullRequest
1 голос
/ 27 марта 2009

Допустим, у меня есть следующая функция, которую я хочу проверить:

public void CancelOrder(Order order)
{
    order.Status = "Cancelled";

    _emailService.SendEmail(order.User.Email, "Your order has been cancelled!");
}

Теперь класс Order является сгенерированным SubSonic-классом, и свойство User в нем загружается с отложенной загрузкой, что означает, что когда я вызываю order.User.Email, он фактически выполняет оператор SQL для извлечения пользователя.

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

Мое текущее решение состоит в том, чтобы реорганизовать функцию CancelOrder, чтобы она выглядела следующим образом:

public void CancelOrder(Order order)
{
    order.Status = "Cancelled";

    User user = _userRepository.GetByUserID(order.UserID);

    _emailService.SendEmail(user.Email, "Your order has been cancelled!");
}

Затем я могу заглушить вызов _userRepository.GetUserByID (), чтобы вернуть жестко закодированный объект User.

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

Ответы [ 2 ]

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

Почему вы не хотите, чтобы ваш модульный тест попал в вашу базу данных? Если вы используете MBUnit для написания тестового примера, вы можете просто пометить модульный тест атрибутом RollBack, и любые изменения в базе данных будут отменены.

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

0 голосов
/ 28 марта 2009

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

interface Order {
  public void Status(...); // or property
  public string UserEmail():
} 

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

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

...