工厂/抽象工厂设计模式在单元测试中的应用

P I*_*P I 5 junit design-patterns factory abstract-factory

我被告知用于编写单元测试用例的工厂/抽象工厂设计模式是非常有效的,但我还没有找到任何清楚地演示它的教程.所以,如果有人能指出我任何现有的教程或给我一些伪代码和解释,这将是非常有帮助的:)

Van*_*den 6

根据GoF,抽象工厂模式的目的是提供一个接口,用于创建相关或从属对象的族,而无需指定其conrcete类.

在框架中,抽象工厂通常使用依赖注入来提供,这是编写易于测试的代码的真正关键.依赖注入只意味着依赖关系是通过构造函数"注入"的,而不是在类中新建的.

假设你使用两个工厂为步步高的简单和硬游戏产生依赖关系(这里只有一个依赖关系,Dice):

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

public class NormalGameFactory implements GameFactory
{
  Dice createDice()
  {
    return new RandomDice();
  }
}
Run Code Online (Sandbox Code Playgroud)

对于单元测试目的,你真的更喜欢不使用Dice实现,所以你编写了一个特殊的GameFactory实现:

public class CustomGameFactory implements GameFactory
{
  private Dice mDice;

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

  Dice createDice()
  {
    return mDice;
  }
}
Run Code Online (Sandbox Code Playgroud)

该工厂不必是生产代码树的一部分.您可以通过测试代码为工厂提供特殊的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());
  }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方法,可以为测试目的注入任何具体依赖性.然而,通常在没有抽象工厂的情况下可以实现相同的目的,即不是注入工厂,而是可以注入依赖性本身.