Как InboundPorts в Hexagonal повышают тестируемость - PullRequest
1 голос
/ 28 апреля 2020

В архитектуре портов и адаптеров (гексагональной) у вас есть:

DrivingAdapter -> InboundPort <- [ domain ] -> OutboundPort <- DrivenAdapter

примечание: конечно, порты являются частью домена

Конкретным примером этого может быть:

WebController -> OrderServicePort [ order domain ] -> OrderRepositoryPort <- MongoDbOrderRepositoryAdapter

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

Чего я не понимаю, так это того, как использование интерфейса Порт на левой стороне полезен для тестируемости?

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

Конечно, в InboundPorts есть значение, поскольку они предоставляют только упрощенное представление конкретного класса домена, который его реализует.

Но я не вижу, откуда повышается тестируемость при использовании InboundPorts.

Согласен?

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

TL; DR;

Да, я согласен.


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

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

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

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

Единственная причина для его замены - тестирование самих первичных адаптеров, просто чтобы убедиться, что они указывают на правильный вариант использования. В таком случае нам понадобится что-то вроде интерфейса. Но в таком случае нам все равно нужно загрузить приложение, которое обычно является самой дорогой частью или тестом, поэтому мы могли бы также сделать это как e2e, функциональный или интеграционный тест, где мы также тестируем ядро ​​или часть это.

В некоторых языках, приложениях или контекстах, в некоторых крайних случаях, возможно, это нужно сделать, возможно, это лучший способ. Мы не должны говорить что-то догматическое c, такое как «никогда не делай ...» или «всегда делай ...», это всегда зависит от контекста.

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

0 голосов
/ 30 апреля 2020

Я совсем не согласен.

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

Порты драйверов являются API "шестиугольника" ( "hexagon" = "business logi c" = "application"). Они представляют собой границу варианта использования (transacional), левые края шестиугольника.

Когда вы тестируете шестиугольник изолированно, вы запускаете тесты (адаптеры драйверов) для этих портов и «насмехаетесь» над управляемыми портами.

Как бы вы протестировали поведение (функциональность) шестиугольника, если у вас нет API такого поведения? Вы тестируете API (драйверы портов). Это контракты поведения SUT.

Более того, они позволяют определять бизнес-логику c lekeage при запуске тестов как регрессионных тестов.

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

См .:

https://jmgarridopaz.github.io/content/hexagonalarchitecture.html#tc6 -1-1

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