【问题标题】:Writing specs for a class that behaves differently depending upon constructor arguments根据构造函数参数为行为不同的类编写规范
【发布时间】:2013-04-24 13:26:45
【问题描述】:

如果您有一个根据构造函数参数做出不同响应的类,您将如何为该类编写规范?

class Route
{
  function __construct($url, array $methods = array())
  {
    // stores methods and url in private member variables
    // creates a regex to match $url against incoming request URLs
  }

  public function isMatch($url)
  {
    // checks if the incoming request url matches against this url
  }
}

使用示例:

$a = new Route('/users/:id');
$a->isMatch('/users/1') // returns true;
$b = new Route('/users');
$b->isMatch('/users') // returns true

如果我使用 phpspec 中的 let 函数为这个类设置我的规范:

class Route extends ObjectBehaviour
{
  function let() 
  {
    $this->beConstructedWith('/users/:id')
  }
}

我的规范只能检查此类的行为是否适用于其中一种情况。

我曾考虑添加 setter 方法以允许我对此进行测试,但似乎我会为了测试目的而打破封装。

我正在努力寻找与此相关的任何内容,所以我开始认为这可能是糟糕的代码异味情况。

【问题讨论】:

  • beConstructedWith() 并不总是必须从 let() 方法调用。您也可以从规范中调用它。

标签: php bdd phpspec


【解决方案1】:

beConstructedWith() 并不总是需要从 let() 方法调用。您也可以从规范中调用它。

在我看来,以不止一种方式设置对象并没有错。但是,您应该避免使用doing too much work in the constructor

【讨论】:

    【解决方案2】:
    1. 构造函数只能用于获取将在此处设置为成员属性的变量。这里不应该做进一步的逻辑......
    2. 按照第 1 点的想法,应该有另一个逻辑来确定接下来会发生什么(例如if Object->hasProperty(X) then do x() 等)
    3. 那么评论就会简单明了。

    例子:

    class Route
    {
        private $url;
        private $methods = array();
    
        /**
         * Constructor method, sets the attributes to private member variables
         * @param string $url URL pattern
         * @param array $methods Methods that should be used with given URL
         */
        function __construct($url, $methods = array())
        {
            $this->url      = $url;
            $this->methods  = $methods;
        }
    
        // ...
    
    }
    

    【讨论】:

    • 好的,但是即使我将创建正则表达式的逻辑移到构造函数之外,问题仍然存在于规范中,因为我无法在多个类中设置一个类方式。
    • 那么有一个不好的方法。尽管您将变量推送到构造函数,但类应该始终只有一个具体的表示。您是否应该根据参数有不同的行为您应该使用更多的类来处理每种可能的行为......然后逻辑决定要实例化哪个类。
    • 好的,有道理。一些想法的良好起点,干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    相关资源
    最近更新 更多