PHPUnit测试Mock的方法,它将闭包作为一个参数

时间:2014-05-17 16:50:50

标签: php unit-testing mocking phpunit closures

我编写了一个用来自yaml文件的服务填充DI容器的类。测试以下方法时遇到问题:

private function parseServices(array $services)
{
    foreach ($services as $name => $attr) {
        $this->container[$name] = function() use($attr) {
            $reflect = new \ReflectionClass($attr["class"]);
            $args = $this->parseArguments($attr["arguments"]);

            return $reflect->newInstanceArgs($args);
        };
    }
}

$services是一个包含服务的数组:

array(
    serviceName => array(
        class => className,
        arguments => array(...)
    )
)

方法parseArguments()返回构造函数的简单参数数组。对于测试$container是一个模拟。我想测试一次为每个服务特定参数调用container。我该怎么测试呢?我的想法是这样的:

$this->container
     ->expects($this->at(3))
     ->method('offsetSet')
     ->with('demo',$this->callback());

但这不起作用。

修改

此方法甚至整个类的责任在于填充容器。因此,测试它的最佳方法是检查容器是否正确填充?正如我在评论中写的那样 - 只是不要嘲笑容器,而是使用具体的实现。你觉得怎么样?

1 个答案:

答案 0 :(得分:0)

好吧,也许这不是你的问题的答案,但无论如何都可以提供帮助。

我会将此测试设计为不同。由于您要测试是否正在构建正确的服务,因此使用某些访问器来获取第3个服务并检查它是否是正确类的对象会更容易。

...我刚刚看到EDIT;) - 确切地说!使用设计合理的代码,从“外部”角度测试类更容易。需要在传统系统上进行这种邪恶的模拟,即无法注入依赖关系。

//原始答案 你能解释一下offsetSet是什么吗?

从我在测试中看到的是你试图断言

  1. offsetSet
  2. 上调用方法$this->container
  3. 第三次
  4. 应使用两个参数调用它:
    1. 'demo'字符串和
    2. 无论$this->callback()返回(也许你的意思是回调this->callback应该作为第二个参数传递,而不是调用它的结果?)