如何测试此 class 或将其重写为可测试的? php规范

How to test this class or rewrite it to be testable? phpspec

这个 class 相当简单,如果有空间,它会在字符串中添加一个 Twitter 主题标签。 Twitter 只允许 140 个字符(url 减去 23 个字符)。因此,如果有 space 个标签,标签就会不断添加。

我不认为它 100% 按预期工作,但这与我下面的问题无关。

class Hashtags {

private $url_character_count = 23;
private $characters_allowed = 140;

public function __construct(Article $article)
{
    $this->article = $article;
    $this->characters_remaining = $this->characters_allowed - $this->url_character_count;
}

public function createHashtagString()
{
        $hashtags = '';
        $hashtags .= $this->addEachNodeHashtag();
        $hashtags .= $this->addHashtagIfSpace($this->article->topic_hashtag);
        $hashtags .= $this->addHashtagIfSpace($this->article->pubissue_hashtag);
        $hashtags .= $this->addHashtagIfSpace($this->article->subject_area_hashtag);
        $hashtags .= $this->addHashtagIfSpace('#aviation');
        return $hashtags;
}

private function addEachNodeHashtag()
{
    //Returns a hashtag or calls hashtagString() if it is a comma separated list
}

private function hashtagString()
{
    //Explodes a comma seperated string of hashtags and calls addHashtagIfSpace()

}

private function addHashtagIfSpace($hashtag_string)
{
    if((strlen($hashtag_string) + 1) <= $this->characters_remaining)
    {
        $this->characters_remaining = $this->characters_remaining - strlen($hashtag_string);

        if(empty($hashtag_string))
        {
            return '';
        }

        return ' ' . $hashtag_string;
    }
}

}

这是我的测试,我的问题是这只测试了一种特定情况,其中所有字段都已填写,并且 space 足以容纳所有字段。我应该继续为不同的情况制作一堆这些测试功能吗?我猜大概会有 10 个。我以前从未做过测试,所以我有点不适应,需要指出正确的方向。

谢谢

class HashtagsSpec extends ObjectBehavior
{

function it_creates_hashtag_string_with_all_fields_filled_in(Article $article)
{
    $this->beConstructedWith($article);
    $article->title = 'This is the article title';
    $article->url = 'http://website.com/node/XXX';
    $article->pubissue_hashtag = '#AHASHTAG';
    $article->subject_area_hashtag = '#SUBAREA';
    $article->topic_hashtag = '#TOPIC';
    $article->node_hashtags = '#Test1,#Test2,#Test3';

    $this->createHashtagString()->shouldReturn(' #Test1 #Test2 #Test3 #TOPIC #AHASHTAG #SUBAREA #aviation');

}
}

步骤 0

删除您的 class 并通过首先编写规范重新开始。

执行此操作时,您经常会发现自己编写了一个不同的(更简单的)实现,同时使用规范来驱动它。这不会花费太多时间,但您的 class 将受益于更好的设计和可测试性。

当我不知道代码应该是什么样子时,我经常使用这种做法。我先制作原型。一旦设计开始变得清晰,我就删除代码并通过规范重新开始。

您不必真正删除它,进行备份;)

步骤 1

定义您的初始测试列表。这将是您认为需要涵盖的行为列表。它不一定是完整的,它会随着你的进步而发展

您可以从:

开始
  • 如果消息中有空间,它会添加一个主题标签
  • 如果在添加主题标签后消息中有空间,它会添加一个 pubissue 标签
  • 如果在添加主题和发布主题标签后消息中有空间,它会添加一个主题区域主题标签
  • 如果消息中没有空间,它不会添加主题标签
  • 如果添加主题标签后消息中没有空间,则不会添加发布标签
  • 如果在添加主题和发布主题标签后消息中没有空间,它不会添加主题区域主题标签

步骤 2

编写第一份规范。考虑更好的命名,因为标签可能不够具体。还可以为您的 class 考虑一个更好的 API。我选择在方法调用中接受 Article 而不是通过构造函数传递它:

class HashtagsSpec
{
    function it_adds_a_topic_hashtag_if_there_is_room_for_it_in_the_message(Article $article)
    {
        $article->pubissue_hashtag = '#AHASHTAG';
        $article->subject_area_hashtag = '#SUBAREA';
        $article->topic_hashtag = '#TOPIC';
        $article->node_hashtags = '#Test1,#Test2,#Test3';

        $this->createHashtagString($article)->shouldMatch('/#TOPIC/');
    }
}

步骤 3

运行 phpspec 并编写最简单的代码使规范通过。

class Hashtags
{
    public function createHashtagString(Article $article)
    {
        return $article->topic_hashtag;
    }
}

步骤 4

重构 - 改进您在步骤 3 中编写的代码的设计。

可能是没有什么可以改进的,尤其是在第一次迭代中。

随着您的进步,您的代码将变得更加通用,而您的规范将变得更加具体。

步骤 5

重复第 2 步到第 5 步,直到完成。只需选择您要涵盖的下一个行为。它不一定是您列表中的下一个。接下来你觉得什么最好实现。

在整个过程中,您经常会发现以前没有考虑过的新行为或边缘情况。只需将它们添加到您的测试列表中,这样就不会分散您的注意力。