DDD + REST + Unit Testing
От: Stalker. Австралия  
Дата: 12.06.17 07:05
Оценка:
Хочется прояснить несколько вопросов по указанной связке и по архитектурным вопросам в целом.

1) Во-первых DDD + REST, каким образом они вообще обьединяются? Что-то ничего нормального не нагугливается, приводятся тривиальные примеры get/post/put/delete где user/id=5 и никаких примеров из реальной жизни. Как сделать в REST что-то из рязряда GetAllUsersWhoWasBornOnMonday(), ActivateUser(int id), SelectCardsWithZeroBalance(), LoadUserDetailsPage(), AssignUserToGroup(int userID, int groupID)

2) Как производится тестирование слоя DDD и сервисов. Скажем есть у нас домейн класс Person

Person
{
public string Name {get;set}
public string Surname {get;set}
public Date DOB {get;set};
public CalculateAge()
}


и есть сервис который дергается из REST

UserWorkflow
{
   public bool SendUserPromotion(int userID)
    {
      if (userID < 0)
        throw new InvalidUserID();

      User user = UserRepository.GetUser(userID);
      
      if (user == null)
        throw new InvalidUser();

      if (user.CalculateAge() > 18)     
      {
        EmailService.SendPromotionEmail(userID);
        LogService.LogCommunition(userID, "Promotion was send");
        UserRepository.UpdateUserLastPromotionDate(userID);
        return true;
      }
       else
      {
        LogService.LogError(userID, "Promotion was not send, user is too young");       
        return false;
      }
    
}


Понятно, что тут для юнит-тестирования следует замокить email service и repository, однако есть пара вопросов:

— Как проверить что EmailService, LogService и UserRepository были вызваны с нужными параметрами (юзер старше 18 лет) или не вызваны?
— Что делать собственно с домейн классом Person, если я его напрямую использую в тесте сервиса, то это вроде уже не юнит тест будет, а интеграционный, а мокить Person через интерфейс будет откровенный ужас и оверкилл
— Стоит-ли тестировать Person.CalculateAge() метод в этом случае

— Обьединяя с вопросом номер 1 — как будет SendUserPromotion() операция выглядить через интерфейс REST?


3) Вопрос по Репозиторию. Очевидно его интерфейс быстро обрастает методами UpdateUserLastPromotionDate(), GetAllUsersWhoWasBornOnMonday() и AssignUserToGroup(). Какие существуют методы по структуризации всего этого, что-бы его класс не превращался в свалку из десятков таких разношерстных методов?
Скажу сразу я знаю о существовании идеи не использовать репозиторий вообще, а прямо в методе сервиса писать соответствующие EF запросы, однако такие идеи хороши в теории, а на практике приводят к лапше из кода бизнес-логики, запросов к данным и конвертации модели данных к бизнес-моделям, а самое главное для написания юнит-тестов всего этого проходится мокить сам EF контекст, что отнимает жуткое количество времени, и позволяет тестить только простейшие запросы
Отредактировано 12.06.2017 23:15 Stalker. . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.