Java 8: статические помощники против стандартных методов для общих утверждений теста
Я занимаюсь TDD на Java в целом ряде проектов, и мне всегда приходится иметь дело с ситуацией, когда я разделяю некоторые общие утверждения между определенными тестами. Мое предварительное решение Java 8 всегда будет выглядеть так.
Класс с общими утверждениями и статическими методами:
class CommonAssertions {
static void assertCorrectUser(User user) {
// bunch of assertions
}
}
Используется следующим образом:
class FooTest {
@Test
void somethingToDoWithUser() {
User user = // obtain user somehow
CommonAssertions.assertCorrectUser(user);
}
}
теперь с Java 8 Я испытываю соблазн использовать интерфейс с методами по default
для общих утверждений:
interface CommonAssertions {
default assertCorrectUser(User user) {
// bunch of assertions on user
}
}
то вместо статических вызовов я бы разработал свои тесты следующим образом:
class FooTest implements CommonAssertions { ... }
Это очень похоже, но кажется, что второй проще в использовании (экономит кучу статического импорта) и показывает больше о тесте. Код изображения:
class CompanyResourceTest implements UserAssertions, CompanyAssertions, JsonErrorAssertions {... }
Некоторые могут утверждать, что default
был разработан для чего-то совершенно другого, и это неправильное использование. Некоторые могут утверждать, что это так же плохо, как положить кучу констант в interface
и реализовать его. Но действительно ли есть какой-то недостаток в этом подходе?
Недостаток в том, что неясно. Интерфейс - это контракт, в котором детали реализации не указаны. Просто используя все методы по умолчанию, вы злоупотребляете тем, для чего был разработан интерфейс, что в целом делает код более сложным для понимания другими. Java ограничена в том смысле, что она не поддерживает миксины или черты, и использование интерфейсов по умолчанию для этого - это просто хакерский подход.
Статические методы являются нормой для этого в java, но если вы действительно противны им, я бы предложил пару альтернатив:
- Напишите свои тесты на языке, который поддерживает миксины, такие как groovy или scala Создайте общий базовый тестовый класс, например UserTest, и ваши тесты, связанные с вашим пользователем, расширяют это. Не идеально, особенно если вам потребуется множественное наследование. Напишите аннотации, которые могут вводить эти методы в ваш тест, поэтому вы могли бы использовать @UserTest, который будет компилироваться в этих методах.
- Вопросы
- Unit-testing
- Java 8: статические помощники против стандартных методов для общих утверждений теста