【问题标题】:PHPUnit Mocking class constantPHPUnit 模拟类常量
【发布时间】:2014-08-11 20:20:17
【问题描述】:

我正在测试一个注入了依赖项的类。在我的无限聪明中,我在整个代码中分散了对依赖项的类常量的引用。

(对不起这个愚蠢的例子,想偏离 foobar。)

<?php

class Book_PhoneBook extends Book {

    private $author;

    public function __construct(Author $author) {
        $this->author = $author;
    }

    public function getCover() {
        return $this->author->getTitle(Author::NAME_UNKNOWN) . ' - YELLOW PAGES';
    }
}


class Author {
    const NAME_UNKNOWN = 'anonymous';

    public function getTitle($nameStyle) {
        //do complicated calculation of author name
        if ($nameStyle == $this::NAME_UNKNOWN) {
            $name = "Anonymous";
        }

        //do further complicated calculations, modifying $name

        return $name;
    }
}

我的问题是单元测试!当我模拟 Author 时,我收到“致命错误:未定义的类常量 'NAME_UNKNOWN'”。模拟的全部目的是避免包含 Author 类文件,那么处理该常量的正确方法是什么?

我可以将Author 拆分为几个对象,或者拆分依赖于常量的方法,但这会导致很多重复。

【问题讨论】:

  • 你可以模拟方法。
  • 您是否尝试在 Book_PhoneBook 类中使用 $author::NAME_UNKNOWN 来引用常量?毕竟模拟扩展了真实的类。
  • @sectus 我想要 Book_PhoneBook::getCover()。如果我不包含 Author 类(通常在另一个文件中),此测试将失败。我不明白你的评论,我应该嘲笑什么?
  • @gontrollez 你的意思是这样的:return $this-&gt;author-&gt;getTitle($this-&gt;author::NAME_UNKNOWN) . ' - YELLOW PAGES';?这将导致Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

标签: php oop mocking phpunit


【解决方案1】:

您使用来自 Author 的类常量这一事实意味着您依赖于在您的代码中使用该类,因此在您的测试中也是如此。因此,为了测试Book_PhoneBook,您需要有一个带有常量的Author 类。如果类常量将是一系列需要传递给类的标志,则需要使类可用,并在测试中确保加载了原始类。你依赖于 Book_PhoneBook::getCover() 的那个类。

您也可以只在Book_PhoneBook 中使用类常量的字符串值,尽管这会破坏将其设为常量以便您能够在一个地方更改值的目的。

通过您的示例,了解您要实现的目标有点棘手,但由于您想删除Book_PhoneBook 中对Author 的依赖,我会将其更改为如下内容:

<?php

class Book_PhoneBook extends Book {

    private $author;

    public function __construct(Author $author) {
        $this->author = $author;
    }

    public function getCover() {
        return $this->author->getTitle() . ' - YELLOW PAGES';
    }
}


class Author {
    const NAME_UNKNOWN = 'anonymous';

    public function __construct($nameStyle) {
       $this->nameStyle = $nameStyle;
    }

    public function getTitle() {
        //do complicated calculation of author name
        if ($this->nameStyle == $this::NAME_UNKNOWN) {
            $name = "Anonymous";
        }

        //do further complicated calculations, modifying $name

        return $name;
    }
}

这个解决方案确实存在getTitle难以添加其他选项的问题。如果没有更好地了解您通过 getTitle 实现的目标,我无法提供更好的解决方案。

【讨论】:

    【解决方案2】:

    对于将来遇到此类问题的任何人,我根据@Schleis 的回答得出了这个结论:

    class Author {
        const NAME_UNKNOWN = 'anonymous';
    
        private function getTitle($nameStyle) {
            //do stuff, taking $nameStyle into account
            return $name;
        }
    
        public function getAnonymousTitle() {
            return $this->getTitle($this::NAME_UNKNOWN);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-07
      • 2021-06-23
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2017-04-16
      • 1970-01-01
      相关资源
      最近更新 更多