在 PHPUnit 中测试具有依赖关系的对象

2024-02-08

对于在其实现中组成另一个对象的对象,编写单元测试以便仅测试主要对象的最佳方法是什么?简单的例子:

class myObj { 
    public function doSomethingWhichIsLogged()
    {
        // ...
        $logger = new logger('/tmp/log.txt');
        $logger->info('some message');
        // ...
    }
}

我知道可以设计该对象,以便可以注入记录器对象依赖项,从而在单元测试中进行模拟,但情况并非总是如此 - 在更复杂的场景中,您确实需要组合其他对象或调用静态方法。

由于我们不想测试 logger 对象,只想测试 myObj,我们该如何继续?我们是否使用测试脚本创建一个存根“双”?就像是:

class logger
{
    public function __construct($filepath) {}
    public function info($message) {}
}

class TestMyObj extends PHPUnit_Framework_TestCase 
{
    // ...
}

这对于小对象来说似乎是可行的,但对于 SUT 依赖于返回值的更复杂的 API 来说会很痛苦。另外,如果您想像使用模拟对象一样测试对依赖项对象的调用,该怎么办?有没有一种方法可以模拟由 SUT 实例化的对象而不是传入的对象?

我已经阅读了有关模拟的手册页,但它似乎没有涵盖依赖项是组合而不是聚合的这种情况。你怎么做呢?


下列的troelskn建议 这是您应该做什么的基本示例。

<?php

class MyObj
{
    /**
     * @var LoggerInterface
     */
    protected $_logger;

    public function doSomethingWhichIsLogged()
    {
        // ...
        $this->getLogger()->info('some message');
        // ...
    }

    public function setLogger(LoggerInterface $logger)
    {
        $this->_logger = $logger;
    }

    public function getLogger()
    {
        return $this->_logger;
    }
}


class MyObjText extends PHPUnit_Framework_TestCase
{
    /**
     * @var MyObj
     */
    protected $_myObj;

    public function setUp()
    {
        $this->_myObj = new MyObj;
    }

    public function testDoSomethingWhichIsLogged()
    {
        $mockedMethods = array('info');
        $mock = $this->getMock('LoggerInterface', $mockedMethods);
        $mock->expects($this->any())
             ->method('info')
             ->will($this->returnValue(null));

        $this->_myObj->setLogger($mock);

        // do your testing
    }
}

有关模拟对象的更多信息可以找到在手册中 http://www.phpunit.de/manual/3.0/en/mock-objects.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PHPUnit 中测试具有依赖关系的对象 的相关文章

随机推荐