首页 > 解决方案 > 如何使用 Mock 函数在 Phpunit 中获取异常

问题描述

我有一个需要测试的功能。我是使用 Phpunit 模拟对象的新手。

所以在 Symfony 中,我有一个包含一些功能的管理器类,所以我需要测试这些功能:

public function preSendMessage()
    {
        // Check send notification value
        $this->sendSmsNotifications              = $this->kernel->getContainer()->getParameter('send_sms_notifications');
        $this->disableNightTimeNotifications     = $this->kernel->getContainer()->getParameter('disable_night_time_sms_notifications');
        $this->smsStartHour                      = $this->kernel->getContainer()->getParameter('sms_start_hour');
        $this->smsEndHour                        = $this->kernel->getContainer()->getParameter('sms_end_hour');
    }

public function sendMessage($recipientNumber, $message, $communicationLog)
    {
        $this->preSendMessage();

        // Assign extra data
        $this->communicationLog            = $communicationLog;
        $this->communicationLog['created'] = new \DateTime('now');

        // Unable to send sms because sms notifications hasn't turn on
        if (empty($this->sendSmsNotifications) || !$this->sendSmsNotifications) {
            return true;
        }
        // Check recipient number
        if (empty($recipientNumber)) {
            throw new SmsException("Number empty", 0);
        }

        //Clean up recipient number, remove spaces.
        $recipientNumber = str_replace(' ', '', $recipientNumber);

        if (strlen($recipientNumber) > 11 || strlen($recipientNumber) < 8) {
            // Log Errors
            $this->communicationLog['status'] = 'fail';
            $this->communicationLog['error']  = 'Invalid mobile number, must be between 10 and 11 integers long';
            $this->logSms();

            throw new SmsException("Invalid mobile number, must be between 10 and 11 integers long", 0);
        }

        if (strpos($recipientNumber, "04") === 0) {
            $mobileIntFormat = "61".substr($recipientNumber, 1);
        } elseif (strpos($recipientNumber, "02") === 0) {
            $mobileIntFormat = "64".substr($recipientNumber, 1);
        } elseif (strpos($recipientNumber, "07") === 0) {
            $mobileIntFormat = "44".substr($recipientNumber, 1);
        } else {
            $this->communicationLog['status'] = 'fail';
            $this->communicationLog['error']  = 'Invalid Number';
            $this->logSms();

            throw new SmsException("Invalid Number", 0);
        }

        // check if to save for later
        if (!empty($this->disableNightTimeNotifications) && $this->disableNightTimeNotifications == true && strpos($recipientNumber, "07") !== 0) {
            $currentHour = intval(date('G'));

            if ($currentHour >= $this->smsEndHour || $currentHour < $this->smsStartHour) {
                // Log SMS
                 $this->communicationLog['status'] = 'queued';
                 $this->logSms();

                if (!empty($this->communicationLog)) {
                    // Get Entity Manager
                    $this->addIntoCommunicationLogs($this->communicationLog);
                }

                return true;
            }
        }


        // execute request
        $methodResponse = $this->transmitObject->SMS($mobileIntFormat, $body, $this->senderName);

        // parse response into xml object
        $xml = @simplexml_load_string($methodResponse);

        if (empty($xml) || !is_object($xml) || (string) $xml->data->result != 'queued') {
            if (!is_object($xml)) {
                $this->communicationLog['status'] = 'fail';
                $this->communicationLog['error']  = "Message was not added: Object Missing";
                $this->logSms();

                throw new SmsException("Message was not added: Object Missing", 0);
            } else {
                $errorMsg = $this->getSmsErrorMessage($xml, $methodResponse);

                $this->communicationLog['status'] = 'fail';
                $this->communicationLog['error']  = $errorMsg;
                $this->logSms();

                throw new SmsException($errorMsg, 0);
            }
        }

        // Log SMS
        $this->communicationLog['status'] = (!empty($this->communicationLog['error'])) ?  'fail' : 'sent';
        $this->logSms();

        if (!empty($this->communicationLog)) {
            $this->updateCommunicationLog();
        }

        return true;
    }

正如您可能想象的那样,我有很多场景需要使用模拟进行测试。

所以我在测试文件中试过这个:

public function testMobileNumberNotValid()
{
    $inputData = array(
        'brand_id' => '1',
        'request_id' => '2600060',
        'original_number' => '0000000',
        'recipient_number' => 'INPUTYOUROWNPHONENUMBER',
        'message' => "Hi dfgfd NOTEBOOK has been accepted at",
        'event_name' => 'some.event',
        'type' => 'sms',
        'server' => ''
    );

    $stub = $this->getMockBuilder(SmsManager::class)
        ->disableOriginalConstructor()
        ->setMethods([
            'toString',
            'logSms',
            'preSendMessage',
            'sendMessage'
        ])//this only to make sure that we wont mock any other objects
        ->getMock();

    $stub->expects($this->once())
        ->method('sendMessage')
        ->will($this->returnSelf());
    $stub->sendMessage('',$inputData['message'],$inputData);
}

正如您在测试函数中看到的那样,我没有通过,recipentNumber所以它不会抛出应该抛出的异常。那么你能帮我解决我哪里错了吗?我想测试 function 的每个场景sendMessage()

标签: phpsymfonymockingphpunit

解决方案


推荐阅读