【问题标题】:With function in mockery with datetime objects带有日期时间对象的模拟功能
【发布时间】:2017-08-20 18:38:22
【问题描述】:

我正在尝试模拟一个方法,该方法应该有一个设置值的日期时间对象传递给它

$mock->shouldReceive('setDatetime')
            ->with($datetime)
            ->once;

我对嘲弄还很陌生,但我不明白“with”是如何工作的。如果 $datetime 是传递给 'setDatetime' 的确切对象,那么它完全满足条件。如果它是一个 datetime 对象,但不是完全相同的对象,即所有值都相同,但它是不同的实例化 DateTime 对象,则它不起作用。我当前传递给 setDatetime 的 Datetime 对象已使用 DateInterval 进行了更改。无论如何我可以测试收到的日期时间对象是否具有相同的值,即使它不是同一个对象。

【问题讨论】:

    标签: php phpunit mockery symfony-2.8


    【解决方案1】:

    另一种解决方案是使用\Hamcrest\Matchers::equalTo。通过这种方式,您可以将比较显式设置为==(等于)而不是===(严格)。您只需要对对象使用它,因为对于原语,它会自动检查 == 比较作为后备。

    例子:

    $mock->shouldReceive('setDatetime')
        ->with(\Hamcrest\Matchers::equalTo($datetime))
        ->once;
    

    文档中写道:

    最常见的匹配器是 with() 匹配器:

    它告诉 mockery 它应该接收一个以整数 1 作为参数的 foo 方法的调用。在这种情况下,Mockery 首先尝试使用 ===(相同)比较运算符匹配参数。如果参数是原语,并且相同比较失败,Mockery 会回退到 ==(等于)比较运算符。

    当匹配对象作为参数时,Mockery 只进行严格的 === 比较,这意味着只有相同的 $object 会匹配。

    来源:http://docs.mockery.io/en/latest/reference/argument_validation.html

    【讨论】:

      【解决方案2】:

      这可以通过给你的 with() 一个闭包来实现。

      给 with 函数提供闭包 Mockery 给你一个闭包匹配器

      Mockery\Matcher\Closure
      

      这个类将采用一个闭包并使用它来匹配你得到的值。

      你将如何实现它是这样的:

      $expectedDateTime = new DateTime();
      $mock->shouldReceive('setDatetime')
                  ->with
                     (new Closure(
                       function($datetime) use ($expectedDateTime) {
                         return $datetime->getTimestamp() === $expectedDateTime->getTimeStamp()
                       }
                     )
                  )->once;
      

      epextedDateTime 当然是它应该是的日期时间,但出于此处添加的示例目的。如果您在断言之外不需要它,您也可以在闭包中创建该 DateTime 对象,那么您将不需要在闭包中使用。

      当然你可以在闭包中检查/断言你想要的任何东西,例如我做了最简单的测试来检查时间戳是否相等。

      【讨论】:

        【解决方案3】:

        当我只想检查几个参数中的一个时遇到问题,其中一个参数应该是 \DateTime,但我对该值并不特别感兴趣,我需要检查另一个参数并返回特定数据对于这个论点,这就是我所做的:

        $dataRepository->shouldReceive('someMethod')
          ->withArgs(function (...$args)) {
            // for example, $args[3] could be \DateTime, but I don't care about it
            return $args[1] = 99,
          })
          ->andReturn([
            new dataObject(99, 1),
            new dataObject(99, 2),
            new dataObject(99, 3),
          ]);
        
        $dataRepository->shouldReceive('someMethod')
          ->withArgs(function (...$args)) {
            // for example, $args[3] could be \DateTime, but I don't care about it
            return $args[1] = 101,
          })
          ->andReturn([
            new dataObject(101, 1),
            new dataObject(101, 2),
            new dataObject(101, 5),
          ]);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-19
          • 1970-01-01
          • 1970-01-01
          • 2012-05-17
          • 1970-01-01
          • 2019-10-26
          相关资源
          最近更新 更多