несколько тестовых классов для интерфейса, свернутых в пакет в junit 4?

#java #interface #junit

#java #интерфейс #junit

Вопрос:

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

Все это прекрасно, за исключением того, что у меня есть куча разных классов (около 10 на данный момент), каждый из которых выполняет множество тестов на основе некоторых реальных данных. Это означает, что для каждой конкретной реализации я в конечном итоге пишу множество тестовых классов, содержащих только метод создания экземпляра.

Мне все это показалось немного запутанным, и мне было интересно, знает ли кто-нибудь о лучшем решении. Я думаю, в идеале я хотел бы иметь возможность передавать заводской объект GraphSearcher в какой-то набор тестов и запускать все различные тестовые классы. Это означало бы, что мне нужно было бы написать лишь крошечный фрагмент кода, чтобы новая реализация GraphSearcher выполнялась со всеми тестами. Я просто не уверен, как это сделать с помощью junit 4. Я уверен, что должен быть какой-то довольно стандартный способ сделать это, но я пока ничего не смог найти. Любые указатели, которые у кого-либо есть, были бы высоко оценены

Ответ №1:

Если я хорошо понимаю вашу проблему, у вас просто есть некоторый тестовый код, и вы хотели бы запускать его несколько раз, каждый раз с другой реализацией GraphSearcher, верно? Если это так, я бы, вероятно, выбрал параметризованный JUnit runner. Это может выглядеть следующим образом:

 @RunWith(Parameterized.class)
public class GraphSearcherTest
{
    private GraphSearcher testedSearcher;

    public GraphSearcherTest(GraphSearcher searcher)
    {
        this.testedSearcher = searcher;
    }

    @Parameters
    public static Collection<Object[]> getParameters()
    {
        return Arrays.asList(new Object[][] {
                { new GraphSearcherImpl1() },
                { new GraphSearcherImpl2() }
        });
    }

    @Test
    public void testGraphSearcher()
    {
        // execute the test
        testedSearcher.search();

        // make some assertions
    }
}
  

Ключевыми частями являются:

  • @RunWith(Parameterized.class) аннотация
  • конструктор, который использует протестированную реализацию GraphSearcher
  • аннотированный @Parameters метод (с произвольным именем), который возвращает коллекцию. Этот метод будет вызываться для каждого элемента коллекции, и объект из коллекции будет добавлен в конструктор теста.
  • размер объекта[] в коллекции должен соответствовать количеству аргументов конструктора

Таким образом, в этом случае тест будет вызван дважды. Первый тест получит экземпляр GraphSearcherImpl1, а второй экземпляр GraphSearcherImpl2 в своем конструкторе.

Комментарии:

1. Это сработало отлично, и большое вам спасибо за ваш быстрый ответ, я действительно ценю это

Ответ №2:

Вы могли бы использовать аннотацию @Parameters, чтобы предоставить вам различные реализации интерфейса.

Например: http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test /