Применение одного теста к двум отдельным классам - PullRequest
2 голосов
/ 16 ноября 2009

У меня есть два разных класса, которые имеют общий интерфейс. Хотя функциональность одинакова, они работают по-разному внутри. Поэтому, естественно, я хочу проверить их обоих.

Лучший пример, который я могу придумать; я сериализовать что-то в файл, один класс сериализовать его в открытый текст, другой в XML. Данные (должны) выглядеть то же самое до и после сериализация независимо от метода б.

Как лучше всего тестировать оба класса одинаково? Тесты отличаются только тем, как они создают разные классы. Я не хочу копировать весь тест, переименовывать его и менять одну строку.

В настоящее время тесты выполняются в JUnit, но я все равно собираюсь перенести их в NUnit, поэтому код на самом деле не имеет значения. Я больше ищу шаблон проектирования для применения в этом тестовом наборе.

Ответы [ 4 ]

4 голосов
/ 16 ноября 2009

Создайте общий абстрактный базовый тестовый класс для теста.

abstract class BaseTest{

 @Test
 public void featureX(){
    Type t = createInstance();
    // do something with t
 }

 abstract Type createInstance();
}

ConcreteTest extends BaseTest{

    Type createInstace(){
        return //instantiate concrete type here.
    }
}
1 голос
/ 16 ноября 2009

Я стараюсь избегать любых отношений между тестовыми классами. Мне нравится держать тестовые случаи (или классы) как можно более атомарными. Преимущество использования наследования здесь не перевешивает сильную связь, которую вы получаете.

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

Кроме того, я бы избегал создавать файлы во время юнит-тестов, потому что это может занять слишком много времени (+ это может не сработать на сборочном компьютере) и, следовательно, задержать сборку.

1 голос
/ 16 ноября 2009

Я бы повторно использовал код либо с наследованием, либо с агрегацией.

Чтобы получить самый короткий код, я бы переместил создание проверенного экземпляра в метод фабрики, скажем, в класс XmlImplementationTest, и унаследовал от него TextImplementationTest:

XmlImplementationTest extends TestCase
{
  Interface tested = null
  Interface createTested() { return new XmlImplementation() }
  ...
  void setUp() { tested = createTested(); }
}

TextImplementationTest extends XmlImplementationTest
{
  override Interface createTested() { return new TextImplementation() }
}

Это не совсем правильный дизайн ОО, так как TextImplementationTest НЕ XmlImplementationTest. Но обычно вам не нужно заботиться об этом.

Или переадресовать вызовы тестового метода к некоторому общему классу утилит. Это может потребовать больше кода и не показывать правильный класс теста в отчетах о тестировании, но может быть проще для отладки.

0 голосов
/ 16 ноября 2009

В C # я бы использовал общий вспомогательный метод для проверки обоих случаев, например:

internal static void SerializationTestHelper<T>() where T : IMySerialize
{
    T serialize = new T();
    // do some testing
}

[TestMethod]
public void XmlTest()
{
    SerializationTestHelper<XmlSerialize>();
}

[TestMethod]
public void PlainTextTest()
{
    SerializationTestHelper<PlainTextSerialize>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...