我正在测试一个注入了依赖项的类。在我的无限聪明中,我在整个代码中分散了对依赖项类常量的引用。
(抱歉这个愚蠢的例子,想要偏离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
分成几个对象,或者拆分依赖常量的方法,但这会引起很多重复。
答案 0 :(得分:4)
您正在使用来自Author的类常量这一事实意味着您依赖于在您的代码中提供该类,因此也在您的测试中。因此,为了测试Book_PhoneBook
,您需要使用常量Author
类。如果类常量将是您需要传递给类的一系列标志,则需要使该类可用,并且在测试中确保已加载原始类。您依赖于Book_PhoneBook::getCover()
的该课程。
你也可以在你的Book_PhoneBook
中使用类常量的字符串值,尽管这样做会使它成为一个常量,这样你就可以在一个地方改变它。
通过您的示例,了解您要尝试实现的内容有点棘手,但由于您要删除Author
中Book_PhoneBook
的依赖关系,我会将其更改为某些内容像这样:
<?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
尝试实现的目标,我无法提供更好的解决方案。
答案 1 :(得分: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);
}
}