在构造函数中调用的 phpunit 模拟方法
phpunit mock method called in constructor
我测试了一个配置 class,它正在解析一个配置文件并允许我获取应用程序的各种设置。
我的目标是模拟在构造函数中调用的 Config class 的 parse()
方法,并设置此方法在构造函数中返回的内容。
这样,它可以防止 file_get_contents()
被调用(在 parse()
方法中)并使我能够使用 config
[=34] 进行配置 class =] 已经设置为包含属性数组。
但我还没有成功。
代码如下:
配置class:
<?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...
}
}
要测试 Config
class,您只需模拟 Parser
并使用真实配置 class。例如:
<?php
namespace Acme\DemoBundle\Tests;
use Acme\DemoBundle\Example\Config;
class ConfigTest extends \PHPUnit_Framework_TestCase
{
private function getConfigTestMock($configAsArray)
{
$parser = $this->getMockBuilder('\Symfony\Component\Yaml\Parser')
->getMock();
$parser->expects($this->once())
->method('parse')
->willReturn($configAsArray);
$configMock = new Config($parser,"fakePath");
return $configMock;
}
/**
* @test
*/
public function get_returns_false_if_no_path_given()
{
$configMock = $this->getConfigTestMock(['param1' => 'value1']);
$this->assertEquals("value1",$configMock->get("param1"));
// Testing further...
}
}
希望对您有所帮助
我建议你做一个功能测试来模拟与文件系统的交互,而不是对被测试的部分模拟 class。
我最近发现了 William Durand 关于 Symfony2 和 DDD 的vfsStream library used in a great article。
所以你可以在你的 composer.json 中安装这个库(我用 1.4 版本测试了这个解决方案)并尝试这个示例测试 class:
<?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"));
}
}
希望对您有所帮助
我测试了一个配置 class,它正在解析一个配置文件并允许我获取应用程序的各种设置。
我的目标是模拟在构造函数中调用的 Config class 的 parse()
方法,并设置此方法在构造函数中返回的内容。
这样,它可以防止 file_get_contents()
被调用(在 parse()
方法中)并使我能够使用 config
[=34] 进行配置 class =] 已经设置为包含属性数组。
但我还没有成功。
代码如下:
配置class:
<?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...
}
}
要测试 Config
class,您只需模拟 Parser
并使用真实配置 class。例如:
<?php
namespace Acme\DemoBundle\Tests;
use Acme\DemoBundle\Example\Config;
class ConfigTest extends \PHPUnit_Framework_TestCase
{
private function getConfigTestMock($configAsArray)
{
$parser = $this->getMockBuilder('\Symfony\Component\Yaml\Parser')
->getMock();
$parser->expects($this->once())
->method('parse')
->willReturn($configAsArray);
$configMock = new Config($parser,"fakePath");
return $configMock;
}
/**
* @test
*/
public function get_returns_false_if_no_path_given()
{
$configMock = $this->getConfigTestMock(['param1' => 'value1']);
$this->assertEquals("value1",$configMock->get("param1"));
// Testing further...
}
}
希望对您有所帮助
我建议你做一个功能测试来模拟与文件系统的交互,而不是对被测试的部分模拟 class。
我最近发现了 William Durand 关于 Symfony2 和 DDD 的vfsStream library used in a great article。
所以你可以在你的 composer.json 中安装这个库(我用 1.4 版本测试了这个解决方案)并尝试这个示例测试 class:
<?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"));
}
}
希望对您有所帮助