Использование шаблонов фабричного / абстрактного проектирования в модульном тестировании - PullRequest
5 голосов
/ 22 сентября 2011

Мне сказали, что шаблоны проектирования Factory / Abstract Factory для написания примеров модульных тестов очень эффективны, но я не смог найти ни одного учебника, который бы наглядно это демонстрировал. Так что будет очень полезно, если кто-то может указать мне на любой существующий учебник или дать мне некоторый псевдокод и объяснение здесь:)

1 Ответ

6 голосов
/ 09 февраля 2012

Согласно GoF, намерение шаблона Абстрактной фабрики заключается в предоставлении интерфейса для создания семейств связанных или зависимых объектов без указания их классов классов.

В каркасах абстрактные фабрики обычно предоставляются с использованием внедрения зависимостей , и это реальный ключ для написания кода, который легко тестировать. Внедрение зависимостей просто означает, что зависимости «внедряются» через конструктор, а не обновляются внутри класса.

Предположим, вы используете две фабрики для производства зависимостей (здесь только одна зависимость, Dice) для простых и сложных игр в нарды:

public class EasyGameFactory implements GameFactory
{
  Dice createDice()
  {
    return new LuckyDice();
  }
}

public class NormalGameFactory implements GameFactory
{
  Dice createDice()
  {
    return new RandomDice();
  }
}

Для целей модульного тестирования вы действительно предпочитаете не использовать ни одну из реализаций Dice, поэтому вы пишете специальную реализацию GameFactory:

public class CustomGameFactory implements GameFactory
{
  private Dice mDice;

  public CustomGameFactory(Dice dice)
  {
    mDice = dice;
  }

  Dice createDice()
  {
    return mDice;
  }
}

Эта фабрика не должна быть частью вашего производственного кода. Вы снабжаете фабрику специальной реализацией Dice с помощью тестового кода:

public class TestBackgammon
{
  @Test public void shouldReturnDiceThrown() 
  {
    SettableDice dice = new SettableDice();
    Game game = new GameImpl(new CustomGameFactory(dice));

    dice.setDice(new int[] {4, 5});
    game.nextTurn();
    assertArrayEquals(new int[] {4, 5}, game.diceThrown());
  }
}

При таком подходе любая конкретная зависимость может быть введена для целей тестирования. Однако часто того же самого можно достичь без абстрактной фабрики, т. Е. Вместо внедрения фабрики может быть введена сама зависимость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...