在PHPUnit中测试一个调用另一个类的实例

103 阅读1分钟

当我们使用测试双功能时,我们模拟服务并假装我们调用它们。当我们不使用test double功能时,我们不模拟服务,直接调用它们。在测试双倍的情况下,下面的例子就没有意义了,因为如果你破坏了测试的类,你的测试testGetUsersWithMock() ,仍然会通过,因为它实际上没有调用测试的类。我只是向你展示这两个选项如何使用。

ParameterUtil

namespace Application\Util;

class ParameterUtil
{
    const MIN_PAGE = 0;
    const MAX_LIMIT = 5;
    const MIN_LIMIT = 1;

    public function getPage($page)
    {
        if (!$page || $page < 1) {
            $page = self::MIN_PAGE;
        }

        return (int) $page;
    }

    public function getLimit($limit)
    {
        if (!$limit || $limit < 1) {
            $limit = self::MIN_LIMIT;
        } elseif ($limit > self::MAX_LIMIT) {
            $limit = self::MAX_LIMIT;
        }

        return (int) $limit;
    }
}

用户服务

namespace Application\Service;

use Application\Util\ParameterUtil;

class UserService
{
    const USERS = [
        'User 1',
        'User 2',
        'User 3',
        'User 4',
        'User 5',
        'User 6',
        'User 7',
        'User 8',
        'User 9',
        'User 10',
    ];

    private $parameterUtil;

    public function __construct(ParameterUtil $parameterUtil)
    {
        $this->parameterUtil = $parameterUtil;
    }

    public function get($page = null, $limit = null)
    {
        $page = $this->parameterUtil->getPage($page);
        $limit = $this->parameterUtil->getLimit($limit);

        return array_slice(self::USERS, $page, $limit);
    }
}

用户服务测试

namespace tests\Application\Service;

use Application\Service\UserService;
use Application\Util\ParameterUtil;
use PHPUnit\Framework\TestCase;

class UserServiceTest extends TestCase
{
    /** @var ParameterUtil */
    private $parameterUtil;

    protected function setUp()
    {
        $this->parameterUtil = new ParameterUtil();
    }

    protected function tearDown()
    {
        $this->parameterUtil = null;
    }

    /**
     * @dataProvider getUsersDataProvider
     */
    public function testGetUsers($page, $limit, $expected)
    {
        $userService = new UserService($this->parameterUtil);

        $result = $userService->get($page, $limit);

        $this->assertEquals($expected, $result);
    }

    /**
     * @dataProvider getUsersDataProvider
     */
    public function testGetUsersWithMock($page, $limit, $expected)
    {
        $userService = $this->getMockBuilder(UserService::class)
            ->setConstructorArgs([$this->parameterUtil])
            ->getMock();

        $userService->expects($this->any())
            ->method('get')
            ->will($this->returnValue($expected));

        $this->assertEquals($expected, $userService->get($page, $limit));
    }

    public function getUsersDataProvider()
    {
        return [
            [null, null, ['User 1']],
            [1, null, ['User 2']],
            [null, 1, ['User 1']],
            [1, 1, ['User 2']],
            [2, 1, ['User 3']],
            [2, 2, ['User 3', 'User 4']],
        ];
    }
}
$ vendor/bin/phpunit
PHPUnit 5.7.22 by Sebastian Bergmann and contributors.

............                                                      12 / 12 (100%)

Time: 23 ms, Memory: 3.75MB

OK (12 tests, 12 assertions)