【问题标题】:How to fix mockery mock object throwing BadMethodCallException?如何修复抛出 BadMethodCallException 的嘲弄模拟对象?
【发布时间】:2016-03-05 08:04:47
【问题描述】:

在一个 silex 应用程序中,我有一个 KafkaAPiClient 类,它肯定有公共方法 postMessages

<?php

namespace Kopernikus\KafkaWriter;

use Kopernikus\KafkaWriter\Model\AbstractMessage;

/**
 * KafkaApiClient.
 **/
class KafkaApiClient
{

    /**
     * @param AbstractMessage[] $msg
     */
    public function postMessages(array $messages)
    {
        foreach ($messages as $message) {
            $this->postMessage($message);
        }
    }

    public function postMessage(AbstractMessage $msg)
    {
         ...
    }
}

我可以打电话给KafkaAPiClient::postMessages 就好了,但是在测试中模拟课程时:

<?php
namespace unit\Request;

use Kopernikus\KafkaWriter\KafkaApiClient;

/**
 * MockeryMethodsNotBeingCallableTest
 **/
class MockeryMethodsNotBeingCallableTest extends \PHPUnit_Framework_TestCase
{
    public function testMockMethodIsCallable()
    {
        $leMock = \Mockery::mock(KafkaApiClient::class);
        $leMock->postMessages([]);
    }
}

我得到:

1) unit\Request\MockeryMethodsNotBeingCallableTest::testMockMethodIsCallable
BadMethodCallException: Method Mockery_11_Kopernikus_KafkaWriter_KafkaApiClient::postMessages() does not exist on this mock object

~/le-project/tests/unit/Request/MockeryMethodsNotBeingCallableTest.php:14

我很困惑,我期待模拟不会做任何事情,但允许调用方法,以便我以后可以添加我的期望。

虽然我找到了解决方案,但我仍然想知道是否可以默认模拟所有方法,然后检查是否调用了某些方法。

【问题讨论】:

  • 它说它没有 postMessages() 函数?我认为你应该检查 KafkaApiClient
  • @MuratCemYALIN 不,具体的类有方法。我完全确定了这一点,它的模拟没有。
  • 可能是受保护的还是私有的?
  • @MuratCemYALIN 这是公开的,这不是问题。具体类不是问题。

标签: php unit-testing phpunit mockery


【解决方案1】:

模拟对象上存在shouldIgnoreMissing 方法。调用exactly what it says on the tin,即:忽略对尚未定义的方法的调用,导致一个什么都不做的模拟:

$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->shouldIgnoreMissing()
$leMock->postMessages([]);

没有任何意义,它没有任何意义。当我以这种方式实例化模拟时,我的队列出现了另一个错误,因为默认情况下方法将返回 null 并且必须明确声明它们的返回值。

$msg = new Message('dummy-message');
$this->kafkaQueue
     ->shouldIgnoreMissing()
     ->shouldReceive('getMessages')->andReturn([$msg]);

任何对getMessages 的调用现在都将准确返回数组[$msg]

或者,可以通过添加 shouldReceive 来非常明确地说明 Mockery 调用了哪些方法:

public function testMockMethodIsCallable()
{
    $leMock = \Mockery::mock(KafkaApiClient::class);
    $leMock->shouldReceive('postMessages');
    $leMock->postMessages([]);
}

【讨论】:

    猜你喜欢
    • 2015-11-13
    • 2019-08-10
    • 2016-07-12
    • 2017-12-27
    • 2014-01-29
    • 2019-06-26
    • 2023-03-12
    • 2018-04-05
    • 2015-07-17
    相关资源
    最近更新 更多