具有文件系统功能的测试对象

发布于 2024-10-07 00:49:39 字数 253 浏览 4 评论 0原文

我正在编写一些广泛使用文件系统的对象。我不确定测试它们的正确方法是什么。

我知道理论上我应该抽象某些对象中的文件系统功能,然后模拟它们,但在我的情况下这是毫无意义的:我想要测试的类的主要用途是管理文件。所以我在测试新对象时也会遇到同样的问题,只是移动了一级。

我认为进行测试的唯一方法是实际使用文件系统。问题是测试将在浏览器和命令行中运行,因此我需要在每个人都具有写访问权限的目录中工作。而且,这似乎不是一个非常便携的解决方案。

有什么想法吗?

I'm writing some objects which make extensive use of the filesystem. I'm not sure what is the right way to test them.

I know in theory I should abstract filesystem functionality in some objects and then mock them, but it would be quite pointless in my case: the main use of the classes I want to test is to manage files. So I would have the same problem when testing the new objects, just shifted one level.

The only way I can think to make the tests is to actually work with the filesystem. The problem is that tests will be ran both in the browser and on the command line, and so I need to work in a directory with write access by everyone. Moreover, this does not seem to be a very portable solution.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤独陪着我 2024-10-14 00:49:39

您可以使用 vfsStream 模拟文件系统PHPUnit 手册中建议

vfsStream 是虚拟文件系统的流包装器,可能有助于单元测试来模拟真实的文件系统 [...] 如果您的系统上有 PEAR 安装程序,您只需执行以下命令:

$ pear 频道-发现 pear.bovigo.org
$ pear 安装 bovigo/vfsStream-beta

Github 上的示例 以及 维基

You can mock the filesystem with vfsStream as suggested in the PHPUnit Manual:

vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system […] If the PEAR installer is available on your system, you only need to execute the following commands:

$ pear channel-discover pear.bovigo.org
$ pear install bovigo/vfsStream-beta

There is examples at Github and also a Wiki

っ〆星空下的拥抱 2024-10-14 00:49:39

引入非常低级的 php 函数,这些函数除了调用文件系统函数之外什么也不做,并在代码中使用它们。

然后,在您的测试工具中,使用存根(可能记录它们已被调用)覆盖此函数。这样您就可以验证您的代码是否会在实时系统中调用正确的低级 PHP 函数。对于单元测试来说,这就是你能做的一切,真的。

Introduce very low level php functions that do nothing other than call file system functions, and use these within your code.

Then, in your test harness, override this functions with stubs (that possibly record that they've been called). That way you can verify that your code will, in the live system, call the correct low level PHP functions. For a unit test thats all you can do, really.

栖竹 2024-10-14 00:49:39

在我看来,您有三个选择:

  • 接受某些测试作为集成测试更好。通过创建一个供测试运行的小世界(在 %TEMP% 中,基于类/方法名称)来开始测试,然后在完成后销毁它。
  • 检查抽象层,并从类中提取文件 IO。为此创建一个接口。其余的使用集成测试(但这将非常小)。这与上面的不同之处在于,您不是执行 file.Read,而是编写意图,例如 ioThingie.loadSettings()。
  • 模拟 IO(按照上面 Gordon 的建议)。

我通常会混合使用选项一和选项二,并且只在边缘情况下使用选项三,因为我发现在 C# 中模拟原始 IO 层 (System.IO.File) 实际上只表明您可以编写模拟语句,并使您的测试变得有点过于依赖于实现,但是上面的 vfs 看起来像是模拟 FS,而不是对象。

As I see it you have three options:

  • Accept that some tests are better off as Integration Tests. Start the test by creating a little world for the test to run in (in %TEMP%, based on the class/method name) then destroy it when you are done.
  • Examine you layer of abstraction, and extract the file IO from the class. The create a interface for this. The remainder use integration tests (but this will be very small). This differs from above in that instead of doing file.Read you write the intent, say ioThingie.loadSettings().
  • Mock the IO (as suggested by Gordon above).

I normally go with a mix of options one and two and only use three for edge cases as I find in C# mocking the raw IO layer (System.IO.File) really only shows you can write mocking statements, and makes your test a little too dependent on the implementation, however the vfs above looks like it mocks the FS, rather than a the objects.

っ左 2024-10-14 00:49:39

另一种变体是通过 runkit 来模拟使用文件系统的 PHP 函数。不确定这是最好的解决方案,但它有效。
phpunit-mockfunction - PHPUnit 扩展,可以简化模拟 PHP 函数。

所以例子是:

class Tests extends PHPUnit_Framework_TestCase {
    // ... setUp, tearDown, other tests...

    function test_1(){
        $file_size_to_return = 10;

        $fake_filesize = new PHPUnit_Extensions_MockFunction('filesize', $this->obj->tested_method);
        $fake_filesize->expects($this->once())->will($this->returnValue($file_size_to_return));

        $this->obj->tested_method(); // actually run method we want test that contains filesize() function...
    }
}

Another variant is to mock PHP functions that use file system with runkit. Not sure it is the best solution but it works.
There is phpunit-mockfunction - PHPUnit extension that simplifies mocking PHP functions.

So example is:

class Tests extends PHPUnit_Framework_TestCase {
    // ... setUp, tearDown, other tests...

    function test_1(){
        $file_size_to_return = 10;

        $fake_filesize = new PHPUnit_Extensions_MockFunction('filesize', $this->obj->tested_method);
        $fake_filesize->expects($this->once())->will($this->returnValue($file_size_to_return));

        $this->obj->tested_method(); // actually run method we want test that contains filesize() function...
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文