Является ли "плохой практикой" генерация идентификаторов в совокупности при ее создании? Должны ли идентификаторы генерироваться вне агрегата?
Случайные числа во многом похожи на часы - они являются формой общего изменяемого состояния. Иными словами, они относятся к императивной оболочке , а не к функциональному ядру.
Что обычно означает для вашей доменной модели то, что случайность передается в качестве аргумента, а не производится самим агрегатом. Это может означать передачу генератора идентификаторов в модель предметной области или даже создание идентификатора в приложении и передачу сгенерированного идентификатора в качестве значения .
Таким образом, в нашем модульном тесте мы замените генератор случайных чисел, предоставленный целевым приложением, на «случайный» генератор, предоставленный тестом - поскольку тест управляет генератором, используемый идентификатор становится детерминированным c, и, следовательно, вы можете легче его обойти.
В тех случаях, когда вы не довольны тем, что генератор случайных чисел является частью API вашей модели домена, другой вариант - выставить его как часть тестового интерфейса.
// We don't necessarily worry about testing this version, it is "too simple to break"
void doSomethingCool(...) {
doSomethingCool(ID.new, ...);
}
// Unit tests measure this function instead, which is easier to test and has
// all of the complicated logic
void doSomethingCool(ID id, ...) {
// ...
}