День 1502. #DesignPatterns
Паттерн Скромный Объект
Скромный Объект (Humble Object) — это паттерн проектирования, специально предназначенный для упрощения модульного тестирования путём отделения поведения, которое легко обработать (логика предметной области), от поведения, которое трудно обработать (например, внешние события или зависимости). Рассмотрим, что это такое и как его можно использовать.
Программам часто необходимо взаимодействовать с другими частями компьютера или внешним миром, например с базой данных или интернет-сервисом. Но когда мы хотим протестировать наши программы, чтобы убедиться, что они работают правильно, может быть трудно общаться с этими другими частями.
Чтобы решить эту проблему, мы можем использовать паттерн Humble Object, отделив код программы, который должен взаимодействовать с другими частями компьютера или внешним миром, от кода программы, который этого не делает. Код, которому не нужно общаться с внешним миром, гораздо легче тестировать, потому что мы можем тестировать его изолированно, не беспокоясь о других вещах.
Простыми словами: нужно выделить сложные для тестирования части и поместить их в оболочку, вместо которой в тестах вы можете использовать заглушку или мок. Эта оболочка называется Humble object.
У вас когда-нибудь была зависимость от DateTime.Now? Если да, может быть очень сложно иметь стабильные тесты в зависимости от того, что вы делаете с Now. Тесты могут работать в будние дни, но проваливаться в выходные, если вы проверяете это в коде. Поэтому мы можем просто «извлечь» эту часть и поместить её в оболочку:
public interface IDateTimeProvider
{
DateTime Now { get; }
}
public class DateTimeProvider : IDateTimeProvider
{
public DateTime Now => DateTime.Now;
}
public class MyService
{
public MyService(
IDateTimeProvider dateTimeProvider)
{
…
}
}
Мы отделили трудно тестируемые вещи от легко тестируемых. Трудно тестируемые вещи, в идеале, вообще не нуждаются в тестировании. Тестировать DateTime.Now вообще не лучшая идея. Во-первых, как бы вы реализовали такой тест? А во-вторых, это не ваш код. С вашей точки зрения, DateTime.Now — это сторонний код, и не ваша задача его тестировать, просто допустим, что он работает правильно.
В то же время легко тестируемые вещи, как MyService, теперь получают зависимость, которая находится под вашим контролем. В тестах её можно заменить пустышкой или моком.
Итого
Паттерн Humble object может облегчить вашу жизнь, особенно на границах вашей архитектуры. Мы рассмотрели его на примере системного времени, но вы также можете применять это правило для таких вещей, как доступ к вводу-выводу или сети.
Источник: https://steven-giesel.com/blogPost/47acad0a-255c-489b-a805-d0f46bde23e5