- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试使用 vfsStream 模拟文件系统操作(实际上是从 php://input 中读取),但缺乏合适的文档和示例确实阻碍了我。
我正在测试的类的相关代码如下:
class RequestBody implements iface\request\RequestBody
{
const
REQ_PATH = 'php://input',
protected
$requestHandle = false;
/**
* Obtain a handle to the request body
*
* @return resource a file pointer resource on success, or <b>FALSE</b> on error.
*/
protected function getHandle ()
{
if (empty ($this -> requestHandle))
{
$this -> requestHandle = fopen (static::REQ_PATH, 'rb');
}
return $this -> requestHandle;
}
}
我在 PHPUnit 测试中使用的设置如下:
protected function configureMock ()
{
$mock = $this -> getMockBuilder ('\gordian\reefknot\http\request\RequestBody');
$mock -> setConstructorArgs (array ($this -> getMock ('\gordian\reefknot\http\iface\Request')))
-> setMethods (array ('getHandle'));
return $mock;
}
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp ()
{
\vfsStreamWrapper::register();
\vfsStream::setup ('testReqBody');
$mock = $this -> configureMock ();
$this -> object = $mock -> getMock ();
$this -> object -> expects ($this -> any ())
-> method ('getHandle')
-> will ($this -> returnCallback (function () {
return fopen ('vfs://testReqBody/data', 'rb');
}));
}
在实际测试中(调用间接触发 getHandle() 的方法),我尝试设置 VFS 并运行断言,如下所示:
public function testBodyParsedParsedTrue ()
{
// Set up virtual data
$fh = fopen ('vfs://testReqBody/data', 'w');
fwrite ($fh, 'test write 42');
fclose ($fh);
// Make assertion
$this -> object -> methodThatTriggersGetHandle ();
$this -> assertTrue ($this -> object -> methodToBeTested ());
}
这只会导致测试挂起。
显然,我在这里做错了一些事情,但考虑到文档的状态,我无法弄清楚我打算做什么。这是由 vfsstream 引起的,还是 phpunit mock 我需要在这里查看的东西?
最佳答案
那么...如何使用流进行测试? vfsStream 所做的只是为文件系统操作提供自定义流包装器。您不需要成熟的 vfsStream 库来模拟单个流参数的行为——这不是正确的解决方案。相反,您需要编写并注册您自己的一次性流包装器,因为您不是在尝试模拟文件系统操作。
假设您要测试以下简单类:
class ClassThatNeedsStream {
private $bodyStream;
public function __construct($bodyStream) {
$this->bodyStream = $bodyStream;
}
public function doSomethingWithStream() {
return stream_get_contents($this->bodyStream);
}
}
在现实生活中你会:
$phpInput = fopen('php://input', 'r');
new ClassThatNeedsStream($phpInput);
因此,为了对其进行测试,我们创建了自己的流包装器,使我们能够控制传入的流的行为。我无法详细介绍,因为自定义流包装器是一个很大的话题。 但是基本上这个过程是这样的:
因此您的自定义流看起来像:
class TestingStreamStub {
public $context;
public static $position = 0;
public static $body = '';
public function stream_open($path, $mode, $options, &$opened_path) {
return true;
}
public function stream_read($bytes) {
$chunk = substr(static::$body, static::$position, $bytes);
static::$position += strlen($chunk);
return $chunk;
}
public function stream_write($data) {
return strlen($data);
}
public function stream_eof() {
return static::$position >= strlen(static::$body);
}
public function stream_tell() {
return static::$position;
}
public function stream_close() {
return null;
}
}
然后在你的测试用例中你会这样做:
public function testSomething() {
stream_wrapper_register('streamTest', 'TestingStreamStub');
TestingStreamStub::$body = 'my custom stream contents';
$stubStream = fopen('streamTest://whatever', 'r+');
$myClass = new ClassThatNeedsStream($stubStream);
$this->assertEquals(
'my custom stream contents',
$myClass->doSomethingWithStream()
);
stream_wrapper_unregister('streamTest');
}
然后,您可以简单地更改我在流包装器中定义的静态属性,以更改从读取流返回的数据。或者,扩展您的基本流包装器类并注册它以提供不同的测试场景。
这是一个非常基本的介绍,但重点是:不要使用 vfsStream,除非您要模拟实际的文件系统操作——这就是它的设计目的。否则,编写自定义流包装器进行测试。
PHP 提供了一个原型(prototype)流包装器类来帮助您入门:http://www.php.net/manual/en/class.streamwrapper.php
关于php - 尝试使用 VFSStream 测试文件系统操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11700397/
我有这个代码: System.err.print("number of terms = "); System.out.println(allTerms.size()); System.err
我有以下问题:在操作系统是 Linux 的情况下和在操作系统是 MacOs 的情况下,我必须执行不同的操作。 所以我创建了以下 Ant 脚本目标: /u
我正在调用 system("bash ../tools/bashScript\"This is an argument!\"&"),然后我正在调用 close(socketFD) 直接在 system
使用最初生成的随机元素来约束随机数组的连续元素是否有效。 例如:我想生成一组 10 个 addr、size 对来模拟典型的内存分配例程并具有如下类: class abc; rand bit[5:0
我正在创建一个必须使用system(const char*)函数来完成一些“繁重工作”的应用程序,并且我需要能够为用户提供粗略的进度百分比。例如,如果操作系统正在为您移动文件,它会为您提供一个进度条,
我即将编写一些项目经理、开发人员和业务分析师会使用的标准/指南和模板。目标是更好地理解正在开发或已经开发的解决方案。 其中一部分是提供有关记录解决方案的标准/指南。例如。记录解决/满足业务案例/用户需
在开发使用压缩磁盘索引或磁盘文件的应用程序时,其中部分索引或文件被重复访问(为了论证,让我们说一些类似于 Zipfian 分布的东西),我想知道什么时候足够/更好地依赖操作系统级缓存(例如,Debia
我们编写了一个 powershell 脚本,用于处理来自内部系统的图像并将其发送到另一个系统。现在,业务的另一部分希望加入其中,对数据进行自己的处理,并将其推送到另一个系统。打听了一下,公司周围有几个
我正在尝试朗姆酒我的应用程序,但我收到以下错误:System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
所以我在其他程序中没有收到此错误,但我在这个程序中收到了它。 这个程序是一个我没有收到错误的示例。 #include int main() { system("pause"); } // en
我在 c# System.URI.FormatExption 中遇到问题 为了清楚起见,我使用的是 Segseuil 的 Matlab 方法,并且它返回一个图片路径 result。我想为其他用户保存此
我正在尝试像这样设置文本框的背景色: txtCompanyName.BackColor = Drawing.Color.WhiteSmoke; 它不喜欢它,因为它要我在前面添加系统,例如: txtCo
请帮助我解决 System.StackOverflowException我想用 .aspx 将记录写入数据库我使用 4 层架构来实现这一切都正常但是当我编译页面然后它显示要插入数据的字段时,当我将数据
我使用了一些通常由系统调用的API。 因此,我将 android:sharedUserId="android.uid.system" 添加到 manifest.xml, 并使用来自 GIT 的 And
我正在尝试创建一个小型应用程序,它需要对/system 文件夹进行读/写访问(它正在尝试删除一个文件,并创建一个新文件来代替它)。我可以使用 adb 毫无问题地重新挂载该文件夹,如果我这样做,我的应用
我想从没有 su 的系统 priv-app 将/system 重新挂载为 RW。如何以编程方式执行此操作?只会用 Runtime.getruntime().exec() 执行一个 shell 命令吗
我正在尝试制作一个带有登录系统的程序我对此很陌生,但我已经连续工作 8 个小时试图解决这个问题。这是我得到的错误代码 + ServerVersion 'con.ServerVersion' threw
当我“构建并运行”Code::Blocks 中的程序时,它运行得非常好!但是当我从“/bin”文件夹手动运行它时,当它试图用 system() 调用“temp.bat”时,它会重置。这是为什么?它没有
我想使用 system/pipe 命令来执行具有特殊字符的命令。下面是示例代码。通过系统/管道执行命令后,它通过改变特殊字符来改变命令。我很惊讶地看到系统命令正在更改作为命令传递的文本。 run(ch
我是一名优秀的程序员,十分优秀!