Java 8: статические помощники против стандартных методов для общих утверждений теста

105
11

Я занимаюсь 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 и реализовать его. Но действительно ли есть какой-то недостаток в этом подходе?

спросил(а) 2015-04-13T01:00:00+03:00 5 лет, 10 месяцев назад
1
Решение
96

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

Статические методы являются нормой для этого в java, но если вы действительно противны им, я бы предложил пару альтернатив:

    Напишите свои тесты на языке, который поддерживает миксины, такие как groovy или scala Создайте общий базовый тестовый класс, например UserTest, и ваши тесты, связанные с вашим пользователем, расширяют это. Не идеально, особенно если вам потребуется множественное наследование. Напишите аннотации, которые могут вводить эти методы в ваш тест, поэтому вы могли бы использовать @UserTest, который будет компилироваться в этих методах.

ответил(а) 2015-04-13T01:11:00+03:00 5 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема