constructor - 在构造函数中调用 phpunit 模拟方法

标签 constructor mocking phpunit

我测试了一个配置类,它正在解析配置文件并允许我获取应用程序的各种设置。

我的目标是模拟 Config 类的 parse() 方法,该方法在构造函数中调用,并设置该方法在构造函数中返回的内容。

这样,它可以防止调用 file_get_contents() (在 parse() 方法中),并使我能够拥有一个带有 config 的 Config 类 属性已设置为包含属性数组。

但我还没有成功做到这一点。

这是代码:

配置类:

<?php namespace Example;

use Symfony\Component\Yaml\Parser;

class Config
{

private $parser;
private $config;

public function __construct(Parser $parser, $filePath)
{
    $this->parser = $parser;
    $this->config = $this->parse($filePath);
}

public function parse($filePath)
{
    $fileAsString = file_get_contents($filePath);

    if (false === $fileAsString) {
        throw new \Exception('Cannot get config file.');
    }

    return $this->parser->parse($fileAsString);
}

public function get($path = null)
{
    if ($path) {
        $config = $this->config;

        $path = explode('/', $path);

        foreach ($path as $bit) {
            if (isset($config[$bit])) {
                $config = $config[$bit];
            }
        }

        return $config;

    }

    return false;
    }

}

测试:

<?php namespace Example;

class ConfigTest extends \PHPUnit_Framework_TestCase
{

    private function getConfigTestMock($configAsArray)
    {
        $parser = $this->getMockBuilder('\Symfony\Component\Yaml\Parser')
            ->getMock();

        $configMock = $this->getMockBuilder('Example\Config')
            ->setConstructorArgs([$parser, $configAsArray])
            ->setMethods(['parse', 'get'])
            ->getMock();

        $configMock->expects($this->once())
            ->method('parse')
            ->willReturn($configAsArray);

        return $configMock;
    }

    /**
     * @test
     */
    public function get_returns_false_if_no_path_given()
    {
        $configMock = $this->getConfigTestMock(['param1' => 'value1']);

        // Testing further...

    }
}

最佳答案

我建议您进行功能测试,模拟与文件系统的交互,而不对测试的类进行部分模拟。

我最近发现了vfsStream great article 中使用的库William Durand 关于 Symfony2 和 DDD 的内容。

所以你可以在你的composer.json中安装这个库(我用1.4版本测试了该解决方案)并尝试这个示例测试类:

<?php


namespace Acme\DemoBundle\Tests;


use Acme\DemoBundle\Example\Config;
use org\bovigo\vfs\vfsStream;
use Symfony\Component\Yaml\Parser;

class ConfigTest extends \PHPUnit_Framework_TestCase
{


    /**
     * @test
     */
    public function valid_content()
    {
        $content = "param1: value1";

        $root      = vfsStream::setup();

        $file = vfsStream::newFile('example.txt')
            ->withContent($content)
            ->at($root);

        $filepath = $file->url();
        $parser = new Parser();

        $config = new Config($parser, $filepath);
        $this->assertEquals("value1", $config->get("param1"));

    }

}

希望这有帮助

关于constructor - 在构造函数中调用 phpunit 模拟方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31411700/

相关文章:

dart - 构造函数:将预处理的参数存储在传递给最终字段的辅助变量中

java - 未声明的实例变量的初始化

c++ - 在编译时检测是否存在默认构造函数

unit-testing - 如何在 Jasmine 中模拟 Angular 服务的功能

c# - 使用 Moq 模拟事件(基于事件的异步模式) - 如何对 UT 中的事件使用react?

php - 如何更改单元测试的应用程序 URL?

c++ - 你能关闭 C++ 中的默认复制构造函数吗?

java - 使用jmock如何重用参数

php - 在 YAML 文件中测试配置的位置

php - 使用登录的 Web 用户进行 Yii 单元测试