#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 /