2

我在将对象传递给其构造函数的类上使用类型提示。传递的对象(Bar)存在于它自己的命名空间中。这一切都很好,直到我将传递的对象换成一个假的(用于单元测试目的)。我的测试 Bar 对象位于它自己的命名空间中,现在(非常正确地)抛出了一个错误。

use Some\Place\Bar
class Foo {
    // Passing a test Bar into here now throws error.
    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }

}

我是 PHP 新手,所以不确定什么是可能的。有没有办法解决这个问题,还是我只需要从课程中删除类型提示(这是我目前的解决方案)?

4

2 回答 2

3

几个选项中的 2 个:

在实现接口 IBar 的构造函数中传递一个对象:

 interface IBar{
  function baz();
 }

 class Bar implements IBar{
    function baz(){ return $this->getSomethingExpensiveFromDatabase();}
 }

 class FakeBar implements IBar{
    function baz(){ return "baz";}
 }

 class Foo {
 function __construct(IBar $bar) ...

或不使用类型提示

function __construct($bar) 

关键是,方法的签名永远不应该依赖于实现,总是依赖于接口。

编辑:所以你只需要导入接口,然后导入假类,无论它来自哪里。FakeBar 然后可以模拟 Bar。

于 2013-01-30T22:28:38.503 回答
1

类型杂耍是完全不同的事情,您在这里展示的是类型提示。您不能传入具有相同类名但位于不同命名空间中的对象,但您可以从一个类中传入一个对象,该类继承自您的方法所期望的类:

namespace Testing;
use Some\Place\Bar;
class TestingBar extends Bar {
}

然后,您可以将 TestingBar 的实例传递给您的方法。

如果您想对原始 Bar 类和测试 Bar 类使用相同的名称,则需要将其中一个别名化(但我建议不要这样做):

namespace Testing;
use Some\Place\Bar as OriginalBar;

class Bar extends OriginalBar {
}
于 2013-01-30T22:35:07.317 回答