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

发布于 2024-12-06 03:39:02 字数 102 浏览 1 评论 0原文

有人告诉我,用于编写单元测试用例的工厂/抽象工厂设计模式非常有效,但我还没有找到任何清楚演示它的教程。因此,如果有人可以向我指出任何现有的教程或在这里给我一些伪代码和解释,那将非常有帮助:)

I am told that the Factory / Abstract Factory Design Patterns for writing Unit Test cases is very effective but I havent been able to find any tutorial which clearly demonstrates it. So it will be very helpful if somebody can point me to any existing tutorial or give me some pseudo code and explanation here :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

上课铃就是安魂曲 2024-12-13 03:39:02

根据 GoF 的说法,抽象工厂模式的意图是提供一个接口,用于创建相关或依赖对象系列,而无需指定它们的具体类。

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

假设您使用两个工厂来为西洋双陆棋的简单游戏和困难游戏生成依赖项(这里只有一个依赖项,Dice):

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

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

GameFactory 的特殊实现:

public class CustomGameFactory implements GameFactory
{
  private Dice mDice;

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

  Dice createDice()
  {
    return mDice;
  }
}

出于单元测试的目的,您确实不希望使用任何一个 Dice 实现,因此您编写了一个 工厂不必是您的生产代码树的一部分。您可以通过测试代码为工厂提供 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());
  }
}

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

According to GoF, the intent of the Abstract Factory pattern is to provide an interface for creating families of related or dependent objects without specifying their conrcete classes.

In frameworks abstract factories are typically provided using dependency injection, and this is the real key to write code which is easy to test. Dependency injection just means that dependencies are "injected" through the constructor, rather than newed inside the class.

Suppose you use two factories to produce dependencies (here just one dependency, Dice) for easy and hard games of backgammon:

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

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

For unit testing purposes you would really prefer to use neither of the Dice implementations, so you write a special implementation of GameFactory:

public class CustomGameFactory implements GameFactory
{
  private Dice mDice;

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

  Dice createDice()
  {
    return mDice;
  }
}

This factory would not have to be part of your production code tree. You supply the factory with a special implementation of Dice through the test code:

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());
  }
}

With this approach any concrete dependency can be injected for testing purposes. However, often the same can be achieved without an Abstract Factory, i.e. rather than injecting a factory, the dependency itself can be injected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文