doubi1910 2012-09-22 10:45
浏览 60
已采纳

PHPUnit - 我是否认为我不能使用模拟来测试依赖注入容器?

I'm unit testing a Dependency Injection Container.

At the most basic level, I'm testing that object graph creation is happening correctly. This uses a mixture of reflection and rules loaded into the DIC.

The DIC works using class definitions and because of the dependencyless nature of mocks, am I right in thinking they are not suitable for this task?

Without using mocks, here's how one of my tests looks:

public function testObjectGraphCreation() {
    $a = $this->dic->create('A');
    $this->assertInstanceOf('B', $a->b);
    $this->assertInstanceOf('C', $a->b->c);
    $this->assertInstanceOf('D', $a->b->c->d);
    $this->assertInstanceOf('E', $a->b->c->e);
    $this->assertInstanceOf('F', $a->b->c->e->f);
} 

(obviously this chaining and public dependencies are only there for the test)

And I've defined several classes in order to make this work:

class A {
    public $b;

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

class B {
    public $c;

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

class C {
    public $d;
    public $e;

    public function __construct(D $d, E $e) {
        $this->d = $d;
        $this->e = $e;
    }
}


class D {

}
class E {
    public $f;
    public function __construct(F $f) {
        $this->f = $f;
    }
}

class F {}

Because of the nature of this test, am I right in thinking I cannot use generated mocks for this?

  • 写回答

2条回答 默认 最新

  • duanhe8280 2012-09-22 22:18
    关注

    This looks more like an integration test where you're testing the entire DI system at once. Instead, see where you can mock parts of the system--not the objects it creates. Without seeing the classes involved, I can't make an educated guess.

    While you probably can't use PHPUnit's mock objects, you can roll your own one-off mocks that do the same thing. For example, to test setting a property by calling Database::setPassword with a value taken from the container you'd create a mock Database class, put the password into the container, and ask the container to create the object.

    class MockDatabase {
        public $passwordSet = false;
        public function setPassword($password) {
            if ($password != 'password') {
                throw new InvalidArgumentException('Expected "password"');
            }
            $this->passwordSet = true;
        }
    }
    
    ...
    
    function testInjectProperty() {
        $container = Container::create(array(
            'password' => 'password',
        ));
        $database = $container->create('MockDatabase');
        self::assertTrue($database->passwordSet);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。