【问题标题】:PHPUnit testing Mock's method which takes closure as a paramPHPUnit 测试以闭包为参数的 Mock 方法
【发布时间】:2014-07-06 00:04:44
【问题描述】:

我编写了一个类,它使用来自 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());

但这不起作用。

编辑

这个方法甚至整个类的职责是填充一个容器。所以也许测试它的最好方法是检查容器是否正确填充?正如我在评论中所写 - 只是不要模拟容器,而是使用具体的实现。你怎么看?

【问题讨论】:

  • 或者最简单的解决方案可能是在测试中使用真正的容器对象 parseServices() 进行测试,然后我可以检查容器对象的状态。我的意思是我可以检查容器是否会返回我想要的服务。容器类经过全面测试。顺便说一句,这是疙瘩 -> pimple.sensiolabs.org - 也许会有所帮助。

标签: php unit-testing mocking phpunit closures


【解决方案1】:

好的,也许它不能完全回答您的问题,但无论如何可能会有所帮助。

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

...我刚刚看到 EDIT ;) - 完全正确!使用正确设计的代码,从“外部”的角度测试类会更容易。仅在遗留系统上需要这种邪恶的模拟,即不能注入依赖项。

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

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

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

【讨论】:

  • 这是一个来自 ArrayAccess 接口的方法 -> php.net/manual/en/class.arrayaccess.php 请查看我上面的评论。
  • 是的,你是对的。方法 offseSet 被第三次调用,参数为:'demo' 和闭包/回调
  • 我已经编辑了我的答案 :) 您采用不同测试方法的想法 - 更贴近我的心。这正是我首先要尝试的。
猜你喜欢
  • 2016-01-05
  • 2014-02-08
  • 2011-08-24
  • 2017-10-20
  • 2021-10-19
  • 1970-01-01
  • 2012-10-13
  • 2018-08-05
  • 1970-01-01
相关资源
最近更新 更多